rubyzip 0.9.5 → 1.3.0

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.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +334 -45
  3. data/Rakefile +11 -6
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +208 -0
  6. data/lib/zip/compressor.rb +1 -2
  7. data/lib/zip/constants.rb +61 -8
  8. data/lib/zip/crypto/encryption.rb +11 -0
  9. data/lib/zip/crypto/null_encryption.rb +43 -0
  10. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  11. data/lib/zip/decompressor.rb +4 -4
  12. data/lib/zip/deflater.rb +18 -14
  13. data/lib/zip/dos_time.rb +48 -0
  14. data/lib/zip/entry.rb +700 -0
  15. data/lib/zip/entry_set.rb +86 -0
  16. data/lib/zip/errors.rb +18 -0
  17. data/lib/zip/extra_field/generic.rb +43 -0
  18. data/lib/zip/extra_field/ntfs.rb +90 -0
  19. data/lib/zip/extra_field/old_unix.rb +44 -0
  20. data/lib/zip/extra_field/universal_time.rb +47 -0
  21. data/lib/zip/extra_field/unix.rb +37 -0
  22. data/lib/zip/extra_field/zip64.rb +68 -0
  23. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  24. data/lib/zip/extra_field.rb +101 -0
  25. data/lib/zip/file.rb +443 -0
  26. data/lib/zip/{zipfilesystem.rb → filesystem.rb} +179 -164
  27. data/lib/zip/inflater.rb +29 -28
  28. data/lib/zip/input_stream.rb +173 -0
  29. data/lib/zip/ioextras/abstract_input_stream.rb +111 -0
  30. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  31. data/lib/zip/ioextras.rb +21 -149
  32. data/lib/zip/null_compressor.rb +2 -2
  33. data/lib/zip/null_decompressor.rb +8 -6
  34. data/lib/zip/null_input_stream.rb +3 -2
  35. data/lib/zip/output_stream.rb +189 -0
  36. data/lib/zip/pass_thru_compressor.rb +7 -7
  37. data/lib/zip/pass_thru_decompressor.rb +19 -19
  38. data/lib/zip/{zip_streamable_directory.rb → streamable_directory.rb} +3 -3
  39. data/lib/zip/streamable_stream.rb +56 -0
  40. data/lib/zip/version.rb +3 -0
  41. data/lib/zip.rb +71 -0
  42. data/samples/example.rb +44 -32
  43. data/samples/example_filesystem.rb +16 -18
  44. data/samples/example_recursive.rb +33 -28
  45. data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +26 -28
  46. data/samples/qtzip.rb +22 -31
  47. data/samples/write_simple.rb +12 -13
  48. data/samples/zipfind.rb +31 -39
  49. data/test/basic_zip_file_test.rb +60 -0
  50. data/test/case_sensitivity_test.rb +69 -0
  51. data/test/central_directory_entry_test.rb +69 -0
  52. data/test/central_directory_test.rb +100 -0
  53. data/test/crypto/null_encryption_test.rb +57 -0
  54. data/test/crypto/traditional_encryption_test.rb +80 -0
  55. data/test/data/WarnInvalidDate.zip +0 -0
  56. data/test/data/file1.txt +46 -0
  57. data/test/data/file1.txt.deflatedData +0 -0
  58. data/test/data/file2.txt +1504 -0
  59. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  60. data/test/data/globTest/foo.txt +0 -0
  61. data/test/data/globTest/food.txt +0 -0
  62. data/test/data/globTest.zip +0 -0
  63. data/test/data/gpbit3stored.zip +0 -0
  64. data/test/data/mimetype +1 -0
  65. data/test/data/notzippedruby.rb +7 -0
  66. data/test/data/ntfs.zip +0 -0
  67. data/test/data/oddExtraField.zip +0 -0
  68. data/test/data/path_traversal/Makefile +10 -0
  69. data/test/data/path_traversal/jwilk/README.md +5 -0
  70. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  71. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  72. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  73. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  74. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  75. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  76. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  77. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  78. data/test/data/path_traversal/relative1.zip +0 -0
  79. data/test/data/path_traversal/tilde.zip +0 -0
  80. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  81. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  82. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  83. data/test/data/rubycode.zip +0 -0
  84. data/test/data/rubycode2.zip +0 -0
  85. data/test/data/test.xls +0 -0
  86. data/test/data/testDirectory.bin +0 -0
  87. data/test/data/zip64-sample.zip +0 -0
  88. data/test/data/zipWithDirs.zip +0 -0
  89. data/test/data/zipWithEncryption.zip +0 -0
  90. data/test/deflater_test.rb +65 -0
  91. data/test/encryption_test.rb +42 -0
  92. data/test/entry_set_test.rb +163 -0
  93. data/test/entry_test.rb +154 -0
  94. data/test/errors_test.rb +35 -0
  95. data/test/extra_field_test.rb +76 -0
  96. data/test/file_extract_directory_test.rb +54 -0
  97. data/test/file_extract_test.rb +145 -0
  98. data/test/file_permissions_test.rb +65 -0
  99. data/test/file_split_test.rb +57 -0
  100. data/test/file_test.rb +666 -0
  101. data/test/filesystem/dir_iterator_test.rb +58 -0
  102. data/test/filesystem/directory_test.rb +139 -0
  103. data/test/filesystem/file_mutating_test.rb +87 -0
  104. data/test/filesystem/file_nonmutating_test.rb +508 -0
  105. data/test/filesystem/file_stat_test.rb +64 -0
  106. data/test/gentestfiles.rb +126 -0
  107. data/test/inflater_test.rb +14 -0
  108. data/test/input_stream_test.rb +182 -0
  109. data/test/ioextras/abstract_input_stream_test.rb +102 -0
  110. data/test/ioextras/abstract_output_stream_test.rb +106 -0
  111. data/test/ioextras/fake_io_test.rb +18 -0
  112. data/test/local_entry_test.rb +154 -0
  113. data/test/output_stream_test.rb +128 -0
  114. data/test/pass_thru_compressor_test.rb +30 -0
  115. data/test/pass_thru_decompressor_test.rb +14 -0
  116. data/test/path_traversal_test.rb +141 -0
  117. data/test/samples/example_recursive_test.rb +37 -0
  118. data/test/settings_test.rb +95 -0
  119. data/test/test_helper.rb +234 -0
  120. data/test/unicode_file_names_and_comments_test.rb +62 -0
  121. data/test/zip64_full_test.rb +51 -0
  122. data/test/zip64_support_test.rb +14 -0
  123. metadata +275 -41
  124. data/NEWS +0 -162
  125. data/lib/zip/stdrubyext.rb +0 -77
  126. data/lib/zip/tempfile_bugfixed.rb +0 -195
  127. data/lib/zip/zip.rb +0 -54
  128. data/lib/zip/zip_central_directory.rb +0 -139
  129. data/lib/zip/zip_entry.rb +0 -639
  130. data/lib/zip/zip_entry_set.rb +0 -66
  131. data/lib/zip/zip_extra_field.rb +0 -213
  132. data/lib/zip/zip_file.rb +0 -318
  133. data/lib/zip/zip_input_stream.rb +0 -134
  134. data/lib/zip/zip_output_stream.rb +0 -172
  135. data/lib/zip/zip_streamable_stream.rb +0 -47
@@ -1,41 +1,39 @@
1
- require 'zip/zip'
1
+ require 'zip'
2
2
 
3
3
  module Zip
4
-
5
- # The ZipFileSystem API provides an API for accessing entries in
6
- # a zip archive that is similar to ruby's builtin File and Dir
4
+ # The ZipFileSystem API provides an API for accessing entries in
5
+ # a zip archive that is similar to ruby's builtin File and Dir
7
6
  # classes.
8
7
  #
9
- # Requiring 'zip/zipfilesystem' includes this module in ZipFile
10
- # making the methods in this module available on ZipFile objects.
8
+ # Requiring 'zip/filesystem' includes this module in Zip::File
9
+ # making the methods in this module available on Zip::File objects.
11
10
  #
12
- # Using this API the following example creates a new zip file
11
+ # Using this API the following example creates a new zip file
13
12
  # <code>my.zip</code> containing a normal entry with the name
14
13
  # <code>first.txt</code>, a directory entry named <code>mydir</code>
15
14
  # and finally another normal entry named <code>second.txt</code>
16
15
  #
17
- # require 'zip/zipfilesystem'
18
- #
19
- # Zip::ZipFile.open("my.zip", Zip::ZipFile::CREATE) {
16
+ # require 'zip/filesystem'
17
+ #
18
+ # Zip::File.open("my.zip", Zip::File::CREATE) {
20
19
  # |zipfile|
21
20
  # zipfile.file.open("first.txt", "w") { |f| f.puts "Hello world" }
22
21
  # zipfile.dir.mkdir("mydir")
23
22
  # zipfile.file.open("mydir/second.txt", "w") { |f| f.puts "Hello again" }
24
23
  # }
25
24
  #
26
- # Reading is as easy as writing, as the following example shows. The
25
+ # Reading is as easy as writing, as the following example shows. The
27
26
  # example writes the contents of <code>first.txt</code> from zip archive
28
27
  # <code>my.zip</code> to standard out.
29
28
  #
30
- # require 'zip/zipfilesystem'
31
- #
32
- # Zip::ZipFile.open("my.zip") {
29
+ # require 'zip/filesystem'
30
+ #
31
+ # Zip::File.open("my.zip") {
33
32
  # |zipfile|
34
33
  # puts zipfile.file.read("first.txt")
35
34
  # }
36
35
 
37
- module ZipFileSystem
38
-
36
+ module FileSystem
39
37
  def initialize # :nodoc:
40
38
  mappedZip = ZipFileNameMapper.new(self)
41
39
  @zipFsDir = ZipFsDir.new(mappedZip)
@@ -45,56 +43,59 @@ module Zip
45
43
  end
46
44
 
47
45
  # Returns a ZipFsDir which is much like ruby's builtin Dir (class)
48
- # object, except it works on the ZipFile on which this method is
46
+ # object, except it works on the Zip::File on which this method is
49
47
  # invoked
50
48
  def dir
51
49
  @zipFsDir
52
50
  end
53
51
 
54
52
  # Returns a ZipFsFile which is much like ruby's builtin File (class)
55
- # object, except it works on the ZipFile on which this method is
53
+ # object, except it works on the Zip::File on which this method is
56
54
  # invoked
57
55
  def file
58
56
  @zipFsFile
59
57
  end
60
58
 
61
59
  # Instances of this class are normally accessed via the accessor
62
- # ZipFile::file. An instance of ZipFsFile behaves like ruby's
63
- # builtin File (class) object, except it works on ZipFile entries.
60
+ # Zip::File::file. An instance of ZipFsFile behaves like ruby's
61
+ # builtin File (class) object, except it works on Zip::File entries.
64
62
  #
65
63
  # The individual methods are not documented due to their
66
64
  # similarity with the methods in File
67
65
  class ZipFsFile
68
-
69
66
  attr_writer :dir
70
- # protected :dir
67
+ # protected :dir
71
68
 
72
69
  class ZipFsStat
70
+ class << self
71
+ def delegate_to_fs_file(*methods)
72
+ methods.each do |method|
73
+ class_eval <<-end_eval, __FILE__, __LINE__ + 1
74
+ def #{method} # def file?
75
+ @zipFsFile.#{method}(@entryName) # @zipFsFile.file?(@entryName)
76
+ end # end
77
+ end_eval
78
+ end
79
+ end
80
+ end
81
+
73
82
  def initialize(zipFsFile, entryName)
74
83
  @zipFsFile = zipFsFile
75
84
  @entryName = entryName
76
85
  end
77
86
 
78
- def forward_invoke(msg)
79
- @zipFsFile.send(msg, @entryName)
80
- end
81
-
82
87
  def kind_of?(t)
83
- super || t == ::File::Stat
88
+ super || t == ::File::Stat
84
89
  end
85
90
 
86
- forward_message :forward_invoke, :file?, :directory?, :pipe?, :chardev?
87
- forward_message :forward_invoke, :symlink?, :socket?, :blockdev?
88
- forward_message :forward_invoke, :readable?, :readable_real?
89
- forward_message :forward_invoke, :writable?, :writable_real?
90
- forward_message :forward_invoke, :executable?, :executable_real?
91
- forward_message :forward_invoke, :sticky?, :owned?, :grpowned?
92
- forward_message :forward_invoke, :setuid?, :setgid?
93
- forward_message :forward_invoke, :zero?
94
- forward_message :forward_invoke, :size, :size?
95
- forward_message :forward_invoke, :mtime, :atime, :ctime
91
+ delegate_to_fs_file :file?, :directory?, :pipe?, :chardev?, :symlink?,
92
+ :socket?, :blockdev?, :readable?, :readable_real?, :writable?, :ctime,
93
+ :writable_real?, :executable?, :executable_real?, :sticky?, :owned?,
94
+ :grpowned?, :setuid?, :setgid?, :zero?, :size, :size?, :mtime, :atime
96
95
 
97
- def blocks; nil; end
96
+ def blocks
97
+ nil
98
+ end
98
99
 
99
100
  def get_entry
100
101
  @zipFsFile.__send__(:get_entry, @entryName)
@@ -103,8 +104,8 @@ module Zip
103
104
 
104
105
  def gid
105
106
  e = get_entry
106
- if e.extra.member? "IUnix"
107
- e.extra["IUnix"].gid || 0
107
+ if e.extra.member? 'IUnix'
108
+ e.extra['IUnix'].gid || 0
108
109
  else
109
110
  0
110
111
  end
@@ -112,43 +113,57 @@ module Zip
112
113
 
113
114
  def uid
114
115
  e = get_entry
115
- if e.extra.member? "IUnix"
116
- e.extra["IUnix"].uid || 0
116
+ if e.extra.member? 'IUnix'
117
+ e.extra['IUnix'].uid || 0
117
118
  else
118
119
  0
119
120
  end
120
121
  end
121
122
 
122
- def ino; 0; end
123
+ def ino
124
+ 0
125
+ end
123
126
 
124
- def dev; 0; end
127
+ def dev
128
+ 0
129
+ end
125
130
 
126
- def rdev; 0; end
131
+ def rdev
132
+ 0
133
+ end
127
134
 
128
- def rdev_major; 0; end
135
+ def rdev_major
136
+ 0
137
+ end
129
138
 
130
- def rdev_minor; 0; end
139
+ def rdev_minor
140
+ 0
141
+ end
131
142
 
132
143
  def ftype
133
144
  if file?
134
- return "file"
145
+ 'file'
135
146
  elsif directory?
136
- return "directory"
147
+ 'directory'
137
148
  else
138
- raise StandardError, "Unknown file type"
149
+ raise StandardError, 'Unknown file type'
139
150
  end
140
151
  end
141
152
 
142
- def nlink; 1; end
153
+ def nlink
154
+ 1
155
+ end
143
156
 
144
- def blksize; nil; end
157
+ def blksize
158
+ nil
159
+ end
145
160
 
146
161
  def mode
147
162
  e = get_entry
148
163
  if e.fstype == 3
149
- e.externalFileAttributes >> 16
164
+ e.external_file_attributes >> 16
150
165
  else
151
- 33206 # 33206 is equivalent to -rw-rw-rw-
166
+ 33_206 # 33206 is equivalent to -rw-rw-rw-
152
167
  end
153
168
  end
154
169
  end
@@ -158,7 +173,7 @@ module Zip
158
173
  end
159
174
 
160
175
  def get_entry(fileName)
161
- if ! exists?(fileName)
176
+ unless exists?(fileName)
162
177
  raise Errno::ENOENT, "No such file or directory - #{fileName}"
163
178
  end
164
179
  @mappedZip.find_entry(fileName)
@@ -166,77 +181,75 @@ module Zip
166
181
  private :get_entry
167
182
 
168
183
  def unix_mode_cmp(fileName, mode)
169
- begin
170
- e = get_entry(fileName)
171
- e.fstype == 3 && ((e.externalFileAttributes >> 16) & mode ) != 0
172
- rescue Errno::ENOENT
173
- false
174
- end
184
+ e = get_entry(fileName)
185
+ e.fstype == 3 && ((e.external_file_attributes >> 16) & mode) != 0
186
+ rescue Errno::ENOENT
187
+ false
175
188
  end
176
189
  private :unix_mode_cmp
177
190
 
178
191
  def exists?(fileName)
179
- expand_path(fileName) == "/" || @mappedZip.find_entry(fileName) != nil
192
+ expand_path(fileName) == '/' || !@mappedZip.find_entry(fileName).nil?
180
193
  end
181
- alias :exist? :exists?
194
+ alias exist? exists?
182
195
 
183
196
  # Permissions not implemented, so if the file exists it is accessible
184
- alias owned? exists?
185
- alias grpowned? exists?
197
+ alias owned? exists?
198
+ alias grpowned? exists?
186
199
 
187
200
  def readable?(fileName)
188
- unix_mode_cmp(fileName, 0444)
201
+ unix_mode_cmp(fileName, 0o444)
189
202
  end
190
- alias readable_real? readable?
203
+ alias readable_real? readable?
191
204
 
192
205
  def writable?(fileName)
193
- unix_mode_cmp(fileName, 0222)
206
+ unix_mode_cmp(fileName, 0o222)
194
207
  end
195
- alias writable_real? writable?
208
+ alias writable_real? writable?
196
209
 
197
210
  def executable?(fileName)
198
- unix_mode_cmp(fileName, 0111)
211
+ unix_mode_cmp(fileName, 0o111)
199
212
  end
200
213
  alias executable_real? executable?
201
214
 
202
215
  def setuid?(fileName)
203
- unix_mode_cmp(fileName, 04000)
216
+ unix_mode_cmp(fileName, 0o4000)
204
217
  end
205
218
 
206
219
  def setgid?(fileName)
207
- unix_mode_cmp(fileName, 02000)
220
+ unix_mode_cmp(fileName, 0o2000)
208
221
  end
209
222
 
210
223
  def sticky?(fileName)
211
- unix_mode_cmp(fileName, 01000)
224
+ unix_mode_cmp(fileName, 0o1000)
212
225
  end
213
226
 
214
227
  def umask(*args)
215
228
  ::File.umask(*args)
216
229
  end
217
230
 
218
- def truncate(fileName, len)
219
- raise StandardError, "truncate not supported"
231
+ def truncate(_fileName, _len)
232
+ raise StandardError, 'truncate not supported'
220
233
  end
221
234
 
222
235
  def directory?(fileName)
223
236
  entry = @mappedZip.find_entry(fileName)
224
- expand_path(fileName) == "/" || (entry != nil && entry.directory?)
237
+ expand_path(fileName) == '/' || (!entry.nil? && entry.directory?)
225
238
  end
226
239
 
227
- def open(fileName, openMode = "r", permissionInt = 0644, &block)
228
- openMode.gsub!("b", "") # ignore b option
240
+ def open(fileName, openMode = 'r', permissionInt = 0o644, &block)
241
+ openMode.delete!('b') # ignore b option
229
242
  case openMode
230
- when "r"
231
- @mappedZip.get_input_stream(fileName, &block)
232
- when "w"
233
- @mappedZip.get_output_stream(fileName, permissionInt, &block)
234
- else
235
- raise StandardError, "openmode '#{openMode} not supported" unless openMode == "r"
243
+ when 'r'
244
+ @mappedZip.get_input_stream(fileName, &block)
245
+ when 'w'
246
+ @mappedZip.get_output_stream(fileName, permissionInt, &block)
247
+ else
248
+ raise StandardError, "openmode '#{openMode} not supported" unless openMode == 'r'
236
249
  end
237
250
  end
238
251
 
239
- def new(fileName, openMode = "r")
252
+ def new(fileName, openMode = 'r')
240
253
  open(fileName, openMode)
241
254
  end
242
255
 
@@ -247,43 +260,41 @@ module Zip
247
260
  # Returns nil for not found and nil for directories
248
261
  def size?(fileName)
249
262
  entry = @mappedZip.find_entry(fileName)
250
- return (entry == nil || entry.directory?) ? nil : entry.size
263
+ entry.nil? || entry.directory? ? nil : entry.size
251
264
  end
252
265
 
253
266
  def chown(ownerInt, groupInt, *filenames)
254
- filenames.each { |fileName|
267
+ filenames.each do |fileName|
255
268
  e = get_entry(fileName)
256
- unless e.extra.member?("IUnix")
257
- e.extra.create("IUnix")
258
- end
259
- e.extra["IUnix"].uid = ownerInt
260
- e.extra["IUnix"].gid = groupInt
261
- }
269
+ e.extra.create('IUnix') unless e.extra.member?('IUnix')
270
+ e.extra['IUnix'].uid = ownerInt
271
+ e.extra['IUnix'].gid = groupInt
272
+ end
262
273
  filenames.size
263
274
  end
264
275
 
265
- def chmod (modeInt, *filenames)
266
- filenames.each { |fileName|
276
+ def chmod(modeInt, *filenames)
277
+ filenames.each do |fileName|
267
278
  e = get_entry(fileName)
268
279
  e.fstype = 3 # force convertion filesystem type to unix
269
280
  e.unix_perms = modeInt
270
- e.externalFileAttributes = modeInt << 16
281
+ e.external_file_attributes = modeInt << 16
271
282
  e.dirty = true
272
- }
283
+ end
273
284
  filenames.size
274
285
  end
275
286
 
276
287
  def zero?(fileName)
277
288
  sz = size(fileName)
278
- sz == nil || sz == 0
289
+ sz.nil? || sz == 0
279
290
  rescue Errno::ENOENT
280
291
  false
281
292
  end
282
293
 
283
294
  def file?(fileName)
284
295
  entry = @mappedZip.find_entry(fileName)
285
- entry != nil && entry.file?
286
- end
296
+ !entry.nil? && entry.file?
297
+ end
287
298
 
288
299
  def dirname(fileName)
289
300
  ::File.dirname(fileName)
@@ -302,9 +313,9 @@ module Zip
302
313
  end
303
314
 
304
315
  def utime(modifiedTime, *fileNames)
305
- fileNames.each { |fileName|
316
+ fileNames.each do |fileName|
306
317
  get_entry(fileName).time = modifiedTime
307
- }
318
+ end
308
319
  end
309
320
 
310
321
  def mtime(fileName)
@@ -313,66 +324,64 @@ module Zip
313
324
 
314
325
  def atime(fileName)
315
326
  e = get_entry(fileName)
316
- if e.extra.member? "UniversalTime"
317
- e.extra["UniversalTime"].atime
318
- else
319
- nil
327
+ if e.extra.member? 'UniversalTime'
328
+ e.extra['UniversalTime'].atime
329
+ elsif e.extra.member? 'NTFS'
330
+ e.extra['NTFS'].atime
320
331
  end
321
332
  end
322
333
 
323
334
  def ctime(fileName)
324
335
  e = get_entry(fileName)
325
- if e.extra.member? "UniversalTime"
326
- e.extra["UniversalTime"].ctime
327
- else
328
- nil
336
+ if e.extra.member? 'UniversalTime'
337
+ e.extra['UniversalTime'].ctime
338
+ elsif e.extra.member? 'NTFS'
339
+ e.extra['NTFS'].ctime
329
340
  end
330
341
  end
331
342
 
332
- def pipe?(filename)
343
+ def pipe?(_filename)
333
344
  false
334
345
  end
335
346
 
336
- def blockdev?(filename)
347
+ def blockdev?(_filename)
337
348
  false
338
349
  end
339
350
 
340
- def chardev?(filename)
351
+ def chardev?(_filename)
341
352
  false
342
353
  end
343
354
 
344
- def symlink?(fileName)
355
+ def symlink?(_fileName)
345
356
  false
346
357
  end
347
358
 
348
- def socket?(fileName)
359
+ def socket?(_fileName)
349
360
  false
350
361
  end
351
362
 
352
363
  def ftype(fileName)
353
- @mappedZip.get_entry(fileName).directory? ? "directory" : "file"
364
+ @mappedZip.get_entry(fileName).directory? ? 'directory' : 'file'
354
365
  end
355
366
 
356
- def readlink(fileName)
357
- raise NotImplementedError, "The readlink() function is not implemented"
367
+ def readlink(_fileName)
368
+ raise NotImplementedError, 'The readlink() function is not implemented'
358
369
  end
359
370
 
360
- def symlink(fileName, symlinkName)
361
- raise NotImplementedError, "The symlink() function is not implemented"
371
+ def symlink(_fileName, _symlinkName)
372
+ raise NotImplementedError, 'The symlink() function is not implemented'
362
373
  end
363
374
 
364
- def link(fileName, symlinkName)
365
- raise NotImplementedError, "The link() function is not implemented"
375
+ def link(_fileName, _symlinkName)
376
+ raise NotImplementedError, 'The link() function is not implemented'
366
377
  end
367
378
 
368
379
  def pipe
369
- raise NotImplementedError, "The pipe() function is not implemented"
380
+ raise NotImplementedError, 'The pipe() function is not implemented'
370
381
  end
371
382
 
372
383
  def stat(fileName)
373
- if ! exists?(fileName)
374
- raise Errno::ENOENT, fileName
375
- end
384
+ raise Errno::ENOENT, fileName unless exists?(fileName)
376
385
  ZipFsStat.new(self, fileName)
377
386
  end
378
387
 
@@ -387,7 +396,7 @@ module Zip
387
396
  end
388
397
 
389
398
  def popen(*args, &aProc)
390
- File.popen(*args, &aProc)
399
+ ::File.popen(*args, &aProc)
391
400
  end
392
401
 
393
402
  def foreach(fileName, aSep = $/, &aProc)
@@ -395,20 +404,19 @@ module Zip
395
404
  end
396
405
 
397
406
  def delete(*args)
398
- args.each {
399
- |fileName|
407
+ args.each do |fileName|
400
408
  if directory?(fileName)
401
409
  raise Errno::EISDIR, "Is a directory - \"#{fileName}\""
402
410
  end
403
411
  @mappedZip.remove(fileName)
404
- }
412
+ end
405
413
  end
406
414
 
407
415
  def rename(fileToRename, newName)
408
416
  @mappedZip.rename(fileToRename, newName) { true }
409
417
  end
410
418
 
411
- alias :unlink :delete
419
+ alias unlink delete
412
420
 
413
421
  def expand_path(aPath)
414
422
  @mappedZip.expand_path(aPath)
@@ -422,7 +430,6 @@ module Zip
422
430
  # The individual methods are not documented due to their
423
431
  # similarity with the methods in Dir
424
432
  class ZipFsDir
425
-
426
433
  def initialize(mappedZip)
427
434
  @mappedZip = mappedZip
428
435
  end
@@ -446,7 +453,9 @@ module Zip
446
453
  dirIt
447
454
  end
448
455
 
449
- def pwd; @mappedZip.pwd; end
456
+ def pwd
457
+ @mappedZip.pwd
458
+ end
450
459
  alias getwd pwd
451
460
 
452
461
  def chdir(aDirectoryName)
@@ -462,18 +471,22 @@ module Zip
462
471
  entries
463
472
  end
464
473
 
474
+ def glob(*args, &block)
475
+ @mappedZip.glob(*args, &block)
476
+ end
477
+
465
478
  def foreach(aDirectoryName)
466
479
  unless @file.stat(aDirectoryName).directory?
467
480
  raise Errno::ENOTDIR, aDirectoryName
468
481
  end
469
- path = @file.expand_path(aDirectoryName).ensure_end("/")
482
+ path = @file.expand_path(aDirectoryName)
483
+ path << '/' unless path.end_with?('/')
470
484
  path = Regexp.escape(path)
471
485
  subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$")
472
- @mappedZip.each {
473
- |fileName|
486
+ @mappedZip.each do |fileName|
474
487
  match = subDirEntriesRegex.match(fileName)
475
- yield(match[1]) unless match == nil
476
- }
488
+ yield(match[1]) unless match.nil?
489
+ end
477
490
  end
478
491
 
479
492
  def delete(entryName)
@@ -482,17 +495,16 @@ module Zip
482
495
  end
483
496
  @mappedZip.remove(entryName)
484
497
  end
485
- alias rmdir delete
498
+ alias rmdir delete
486
499
  alias unlink delete
487
500
 
488
- def mkdir(entryName, permissionInt = 0755)
501
+ def mkdir(entryName, permissionInt = 0o755)
489
502
  @mappedZip.mkdir(entryName, permissionInt)
490
503
  end
491
504
 
492
- def chroot(*args)
493
- raise NotImplementedError, "The chroot() function is not implemented"
505
+ def chroot(*_args)
506
+ raise NotImplementedError, 'The chroot() function is not implemented'
494
507
  end
495
-
496
508
  end
497
509
 
498
510
  class ZipFsDirIterator # :nodoc:all
@@ -508,39 +520,39 @@ module Zip
508
520
  end
509
521
 
510
522
  def each(&aProc)
511
- raise IOError, "closed directory" if @fileNames == nil
523
+ raise IOError, 'closed directory' if @fileNames.nil?
512
524
  @fileNames.each(&aProc)
513
525
  end
514
526
 
515
527
  def read
516
- raise IOError, "closed directory" if @fileNames == nil
517
- @fileNames[(@index+=1)-1]
528
+ raise IOError, 'closed directory' if @fileNames.nil?
529
+ @fileNames[(@index += 1) - 1]
518
530
  end
519
531
 
520
532
  def rewind
521
- raise IOError, "closed directory" if @fileNames == nil
533
+ raise IOError, 'closed directory' if @fileNames.nil?
522
534
  @index = 0
523
535
  end
524
536
 
525
537
  def seek(anIntegerPosition)
526
- raise IOError, "closed directory" if @fileNames == nil
538
+ raise IOError, 'closed directory' if @fileNames.nil?
527
539
  @index = anIntegerPosition
528
540
  end
529
541
 
530
542
  def tell
531
- raise IOError, "closed directory" if @fileNames == nil
543
+ raise IOError, 'closed directory' if @fileNames.nil?
532
544
  @index
533
545
  end
534
546
  end
535
547
 
536
- # All access to ZipFile from ZipFsFile and ZipFsDir goes through a
548
+ # All access to Zip::File from ZipFsFile and ZipFsDir goes through a
537
549
  # ZipFileNameMapper, which has one responsibility: ensure
538
550
  class ZipFileNameMapper # :nodoc:all
539
551
  include Enumerable
540
552
 
541
553
  def initialize(zipFile)
542
554
  @zipFile = zipFile
543
- @pwd = "/"
555
+ @pwd = '/'
544
556
  end
545
557
 
546
558
  attr_accessor :pwd
@@ -561,6 +573,10 @@ module Zip
561
573
  @zipFile.get_output_stream(expand_to_entry(fileName), permissionInt, &aProc)
562
574
  end
563
575
 
576
+ def glob(pattern, *flags, &block)
577
+ @zipFile.glob(expand_to_entry(pattern), *flags, &block)
578
+ end
579
+
564
580
  def read(fileName)
565
581
  @zipFile.read(expand_to_entry(fileName))
566
582
  end
@@ -570,40 +586,39 @@ module Zip
570
586
  end
571
587
 
572
588
  def rename(fileName, newName, &continueOnExistsProc)
573
- @zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),
589
+ @zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),
574
590
  &continueOnExistsProc)
575
591
  end
576
592
 
577
- def mkdir(fileName, permissionInt = 0755)
593
+ def mkdir(fileName, permissionInt = 0o755)
578
594
  @zipFile.mkdir(expand_to_entry(fileName), permissionInt)
579
595
  end
580
596
 
581
597
  # Turns entries into strings and adds leading /
582
598
  # and removes trailing slash on directories
583
599
  def each
584
- @zipFile.each {
585
- |e|
586
- yield("/"+e.to_s.chomp("/"))
587
- }
600
+ @zipFile.each do |e|
601
+ yield('/' + e.to_s.chomp('/'))
602
+ end
588
603
  end
589
604
 
590
605
  def expand_path(aPath)
591
- expanded = aPath.start_with?("/") ? aPath : @pwd.ensure_end("/") + aPath
592
- expanded.gsub!(/\/\.(\/|$)/, "")
593
- expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, "")
594
- expanded.empty? ? "/" : expanded
606
+ expanded = aPath.start_with?('/') ? aPath : ::File.join(@pwd, aPath)
607
+ expanded.gsub!(/\/\.(\/|$)/, '')
608
+ expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, '')
609
+ expanded.empty? ? '/' : expanded
595
610
  end
596
611
 
597
612
  private
598
613
 
599
614
  def expand_to_entry(aPath)
600
- expand_path(aPath).lchop
615
+ expand_path(aPath)[1..-1]
601
616
  end
602
617
  end
603
618
  end
604
619
 
605
- class ZipFile
606
- include ZipFileSystem
620
+ class File
621
+ include FileSystem
607
622
  end
608
623
  end
609
624