rubyzip 0.9.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +354 -0
  3. data/Rakefile +15 -104
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +212 -0
  6. data/lib/zip/compressor.rb +9 -0
  7. data/lib/zip/constants.rb +115 -0
  8. data/lib/zip/crypto/decrypted_io.rb +40 -0
  9. data/lib/zip/crypto/encryption.rb +11 -0
  10. data/lib/zip/crypto/null_encryption.rb +43 -0
  11. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  12. data/lib/zip/decompressor.rb +31 -0
  13. data/lib/zip/deflater.rb +34 -0
  14. data/lib/zip/dos_time.rb +53 -0
  15. data/lib/zip/entry.rb +719 -0
  16. data/lib/zip/entry_set.rb +88 -0
  17. data/lib/zip/errors.rb +19 -0
  18. data/lib/zip/extra_field/generic.rb +44 -0
  19. data/lib/zip/extra_field/ntfs.rb +94 -0
  20. data/lib/zip/extra_field/old_unix.rb +46 -0
  21. data/lib/zip/extra_field/universal_time.rb +77 -0
  22. data/lib/zip/extra_field/unix.rb +39 -0
  23. data/lib/zip/extra_field/zip64.rb +70 -0
  24. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  25. data/lib/zip/extra_field.rb +103 -0
  26. data/lib/zip/file.rb +468 -0
  27. data/lib/zip/filesystem.rb +643 -0
  28. data/lib/zip/inflater.rb +54 -0
  29. data/lib/zip/input_stream.rb +180 -0
  30. data/lib/zip/ioextras/abstract_input_stream.rb +122 -0
  31. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  32. data/lib/zip/ioextras.rb +21 -140
  33. data/lib/zip/null_compressor.rb +15 -0
  34. data/lib/zip/null_decompressor.rb +19 -0
  35. data/lib/zip/null_input_stream.rb +10 -0
  36. data/lib/zip/output_stream.rb +198 -0
  37. data/lib/zip/pass_thru_compressor.rb +23 -0
  38. data/lib/zip/pass_thru_decompressor.rb +31 -0
  39. data/lib/zip/streamable_directory.rb +15 -0
  40. data/lib/zip/streamable_stream.rb +52 -0
  41. data/lib/zip/version.rb +3 -0
  42. data/lib/zip.rb +72 -0
  43. data/samples/example.rb +44 -32
  44. data/samples/example_filesystem.rb +16 -19
  45. data/samples/example_recursive.rb +54 -0
  46. data/samples/gtk_ruby_zip.rb +84 -0
  47. data/samples/qtzip.rb +25 -34
  48. data/samples/write_simple.rb +10 -13
  49. data/samples/zipfind.rb +38 -45
  50. metadata +182 -91
  51. data/ChangeLog +0 -1504
  52. data/NEWS +0 -144
  53. data/README +0 -72
  54. data/install.rb +0 -22
  55. data/lib/download_quizzes.rb +0 -119
  56. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +0 -205
  57. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +0 -111
  58. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +0 -111
  59. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +0 -301
  60. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +0 -268
  61. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +0 -132
  62. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +0 -13
  63. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +0 -230
  64. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +0 -24
  65. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +0 -30
  66. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +0 -19
  67. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +0 -31
  68. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +0 -66
  69. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +0 -17
  70. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +0 -2
  71. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +0 -204
  72. data/lib/quiz1/t/solutions/Jim Menard/test.rb +0 -47
  73. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +0 -97
  74. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +0 -140
  75. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +0 -14
  76. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +0 -68
  77. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +0 -146
  78. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +0 -38
  79. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +0 -5
  80. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +0 -27
  81. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +0 -151
  82. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +0 -198
  83. data/lib/zip/stdrubyext.rb +0 -111
  84. data/lib/zip/tempfile_bugfixed.rb +0 -195
  85. data/lib/zip/zip.rb +0 -1847
  86. data/lib/zip/zipfilesystem.rb +0 -609
  87. data/lib/zip/ziprequire.rb +0 -90
  88. data/samples/gtkRubyzip.rb +0 -86
  89. data/test/alltests.rb +0 -9
  90. data/test/data/file1.txt +0 -46
  91. data/test/data/file1.txt.deflatedData +0 -0
  92. data/test/data/file2.txt +0 -1504
  93. data/test/data/notzippedruby.rb +0 -7
  94. data/test/data/rubycode.zip +0 -0
  95. data/test/data/rubycode2.zip +0 -0
  96. data/test/data/testDirectory.bin +0 -0
  97. data/test/data/zipWithDirs.zip +0 -0
  98. data/test/gentestfiles.rb +0 -157
  99. data/test/ioextrastest.rb +0 -208
  100. data/test/stdrubyexttest.rb +0 -52
  101. data/test/zipfilesystemtest.rb +0 -831
  102. data/test/ziprequiretest.rb +0 -43
  103. data/test/ziptest.rb +0 -1599
@@ -1,609 +0,0 @@
1
- require 'zip/zip'
2
-
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
7
- # classes.
8
- #
9
- # Requiring 'zip/zipfilesystem' includes this module in ZipFile
10
- # making the methods in this module available on ZipFile objects.
11
- #
12
- # Using this API the following example creates a new zip file
13
- # <code>my.zip</code> containing a normal entry with the name
14
- # <code>first.txt</code>, a directory entry named <code>mydir</code>
15
- # and finally another normal entry named <code>second.txt</code>
16
- #
17
- # require 'zip/zipfilesystem'
18
- #
19
- # Zip::ZipFile.open("my.zip", Zip::ZipFile::CREATE) {
20
- # |zipfile|
21
- # zipfile.file.open("first.txt", "w") { |f| f.puts "Hello world" }
22
- # zipfile.dir.mkdir("mydir")
23
- # zipfile.file.open("mydir/second.txt", "w") { |f| f.puts "Hello again" }
24
- # }
25
- #
26
- # Reading is as easy as writing, as the following example shows. The
27
- # example writes the contents of <code>first.txt</code> from zip archive
28
- # <code>my.zip</code> to standard out.
29
- #
30
- # require 'zip/zipfilesystem'
31
- #
32
- # Zip::ZipFile.open("my.zip") {
33
- # |zipfile|
34
- # puts zipfile.file.read("first.txt")
35
- # }
36
-
37
- module ZipFileSystem
38
-
39
- def initialize # :nodoc:
40
- mappedZip = ZipFileNameMapper.new(self)
41
- @zipFsDir = ZipFsDir.new(mappedZip)
42
- @zipFsFile = ZipFsFile.new(mappedZip)
43
- @zipFsDir.file = @zipFsFile
44
- @zipFsFile.dir = @zipFsDir
45
- end
46
-
47
- # 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
49
- # invoked
50
- def dir
51
- @zipFsDir
52
- end
53
-
54
- # 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
56
- # invoked
57
- def file
58
- @zipFsFile
59
- end
60
-
61
- # 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.
64
- #
65
- # The individual methods are not documented due to their
66
- # similarity with the methods in File
67
- class ZipFsFile
68
-
69
- attr_writer :dir
70
- # protected :dir
71
-
72
- class ZipFsStat
73
- def initialize(zipFsFile, entryName)
74
- @zipFsFile = zipFsFile
75
- @entryName = entryName
76
- end
77
-
78
- def forward_invoke(msg)
79
- @zipFsFile.send(msg, @entryName)
80
- end
81
-
82
- def kind_of?(t)
83
- super || t == ::File::Stat
84
- end
85
-
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
96
-
97
- def blocks; nil; end
98
-
99
- def get_entry
100
- @zipFsFile.__send__(:get_entry, @entryName)
101
- end
102
- private :get_entry
103
-
104
- def gid
105
- e = get_entry
106
- if e.extra.member? "IUnix"
107
- e.extra["IUnix"].gid || 0
108
- else
109
- 0
110
- end
111
- end
112
-
113
- def uid
114
- e = get_entry
115
- if e.extra.member? "IUnix"
116
- e.extra["IUnix"].uid || 0
117
- else
118
- 0
119
- end
120
- end
121
-
122
- def ino; 0; end
123
-
124
- def dev; 0; end
125
-
126
- def rdev; 0; end
127
-
128
- def rdev_major; 0; end
129
-
130
- def rdev_minor; 0; end
131
-
132
- def ftype
133
- if file?
134
- return "file"
135
- elsif directory?
136
- return "directory"
137
- else
138
- raise StandardError, "Unknown file type"
139
- end
140
- end
141
-
142
- def nlink; 1; end
143
-
144
- def blksize; nil; end
145
-
146
- def mode
147
- e = get_entry
148
- if e.fstype == 3
149
- e.externalFileAttributes >> 16
150
- else
151
- 33206 # 33206 is equivalent to -rw-rw-rw-
152
- end
153
- end
154
- end
155
-
156
- def initialize(mappedZip)
157
- @mappedZip = mappedZip
158
- end
159
-
160
- def get_entry(fileName)
161
- if ! exists?(fileName)
162
- raise Errno::ENOENT, "No such file or directory - #{fileName}"
163
- end
164
- @mappedZip.find_entry(fileName)
165
- end
166
- private :get_entry
167
-
168
- 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
175
- end
176
- private :unix_mode_cmp
177
-
178
- def exists?(fileName)
179
- expand_path(fileName) == "/" || @mappedZip.find_entry(fileName) != nil
180
- end
181
- alias :exist? :exists?
182
-
183
- # Permissions not implemented, so if the file exists it is accessible
184
- alias owned? exists?
185
- alias grpowned? exists?
186
-
187
- def readable?(fileName)
188
- unix_mode_cmp(fileName, 0444)
189
- end
190
- alias readable_real? readable?
191
-
192
- def writable?(fileName)
193
- unix_mode_cmp(fileName, 0222)
194
- end
195
- alias writable_real? writable?
196
-
197
- def executable?(fileName)
198
- unix_mode_cmp(fileName, 0111)
199
- end
200
- alias executable_real? executable?
201
-
202
- def setuid?(fileName)
203
- unix_mode_cmp(fileName, 04000)
204
- end
205
-
206
- def setgid?(fileName)
207
- unix_mode_cmp(fileName, 02000)
208
- end
209
-
210
- def sticky?(fileName)
211
- unix_mode_cmp(fileName, 01000)
212
- end
213
-
214
- def umask(*args)
215
- ::File.umask(*args)
216
- end
217
-
218
- def truncate(fileName, len)
219
- raise StandardError, "truncate not supported"
220
- end
221
-
222
- def directory?(fileName)
223
- entry = @mappedZip.find_entry(fileName)
224
- expand_path(fileName) == "/" || (entry != nil && entry.directory?)
225
- end
226
-
227
- def open(fileName, openMode = "r", &block)
228
- case openMode
229
- when "r"
230
- @mappedZip.get_input_stream(fileName, &block)
231
- when "w"
232
- @mappedZip.get_output_stream(fileName, &block)
233
- else
234
- raise StandardError, "openmode '#{openMode} not supported" unless openMode == "r"
235
- end
236
- end
237
-
238
- def new(fileName, openMode = "r")
239
- open(fileName, openMode)
240
- end
241
-
242
- def size(fileName)
243
- @mappedZip.get_entry(fileName).size
244
- end
245
-
246
- # Returns nil for not found and nil for directories
247
- def size?(fileName)
248
- entry = @mappedZip.find_entry(fileName)
249
- return (entry == nil || entry.directory?) ? nil : entry.size
250
- end
251
-
252
- def chown(ownerInt, groupInt, *filenames)
253
- filenames.each { |fileName|
254
- e = get_entry(fileName)
255
- unless e.extra.member?("IUnix")
256
- e.extra.create("IUnix")
257
- end
258
- e.extra["IUnix"].uid = ownerInt
259
- e.extra["IUnix"].gid = groupInt
260
- }
261
- filenames.size
262
- end
263
-
264
- def chmod (modeInt, *filenames)
265
- filenames.each { |fileName|
266
- e = get_entry(fileName)
267
- e.fstype = 3 # force convertion filesystem type to unix
268
- e.externalFileAttributes = modeInt << 16
269
- }
270
- filenames.size
271
- end
272
-
273
- def zero?(fileName)
274
- sz = size(fileName)
275
- sz == nil || sz == 0
276
- rescue Errno::ENOENT
277
- false
278
- end
279
-
280
- def file?(fileName)
281
- entry = @mappedZip.find_entry(fileName)
282
- entry != nil && entry.file?
283
- end
284
-
285
- def dirname(fileName)
286
- ::File.dirname(fileName)
287
- end
288
-
289
- def basename(fileName)
290
- ::File.basename(fileName)
291
- end
292
-
293
- def split(fileName)
294
- ::File.split(fileName)
295
- end
296
-
297
- def join(*fragments)
298
- ::File.join(*fragments)
299
- end
300
-
301
- def utime(modifiedTime, *fileNames)
302
- fileNames.each { |fileName|
303
- get_entry(fileName).time = modifiedTime
304
- }
305
- end
306
-
307
- def mtime(fileName)
308
- @mappedZip.get_entry(fileName).mtime
309
- end
310
-
311
- def atime(fileName)
312
- e = get_entry(fileName)
313
- if e.extra.member? "UniversalTime"
314
- e.extra["UniversalTime"].atime
315
- else
316
- nil
317
- end
318
- end
319
-
320
- def ctime(fileName)
321
- e = get_entry(fileName)
322
- if e.extra.member? "UniversalTime"
323
- e.extra["UniversalTime"].ctime
324
- else
325
- nil
326
- end
327
- end
328
-
329
- def pipe?(filename)
330
- false
331
- end
332
-
333
- def blockdev?(filename)
334
- false
335
- end
336
-
337
- def chardev?(filename)
338
- false
339
- end
340
-
341
- def symlink?(fileName)
342
- false
343
- end
344
-
345
- def socket?(fileName)
346
- false
347
- end
348
-
349
- def ftype(fileName)
350
- @mappedZip.get_entry(fileName).directory? ? "directory" : "file"
351
- end
352
-
353
- def readlink(fileName)
354
- raise NotImplementedError, "The readlink() function is not implemented"
355
- end
356
-
357
- def symlink(fileName, symlinkName)
358
- raise NotImplementedError, "The symlink() function is not implemented"
359
- end
360
-
361
- def link(fileName, symlinkName)
362
- raise NotImplementedError, "The link() function is not implemented"
363
- end
364
-
365
- def pipe
366
- raise NotImplementedError, "The pipe() function is not implemented"
367
- end
368
-
369
- def stat(fileName)
370
- if ! exists?(fileName)
371
- raise Errno::ENOENT, fileName
372
- end
373
- ZipFsStat.new(self, fileName)
374
- end
375
-
376
- alias lstat stat
377
-
378
- def readlines(fileName)
379
- open(fileName) { |is| is.readlines }
380
- end
381
-
382
- def read(fileName)
383
- @mappedZip.read(fileName)
384
- end
385
-
386
- def popen(*args, &aProc)
387
- File.popen(*args, &aProc)
388
- end
389
-
390
- def foreach(fileName, aSep = $/, &aProc)
391
- open(fileName) { |is| is.each_line(aSep, &aProc) }
392
- end
393
-
394
- def delete(*args)
395
- args.each {
396
- |fileName|
397
- if directory?(fileName)
398
- raise Errno::EISDIR, "Is a directory - \"#{fileName}\""
399
- end
400
- @mappedZip.remove(fileName)
401
- }
402
- end
403
-
404
- def rename(fileToRename, newName)
405
- @mappedZip.rename(fileToRename, newName) { true }
406
- end
407
-
408
- alias :unlink :delete
409
-
410
- def expand_path(aPath)
411
- @mappedZip.expand_path(aPath)
412
- end
413
- end
414
-
415
- # Instances of this class are normally accessed via the accessor
416
- # ZipFile::dir. An instance of ZipFsDir behaves like ruby's
417
- # builtin Dir (class) object, except it works on ZipFile entries.
418
- #
419
- # The individual methods are not documented due to their
420
- # similarity with the methods in Dir
421
- class ZipFsDir
422
-
423
- def initialize(mappedZip)
424
- @mappedZip = mappedZip
425
- end
426
-
427
- attr_writer :file
428
-
429
- def new(aDirectoryName)
430
- ZipFsDirIterator.new(entries(aDirectoryName))
431
- end
432
-
433
- def open(aDirectoryName)
434
- dirIt = new(aDirectoryName)
435
- if block_given?
436
- begin
437
- yield(dirIt)
438
- return nil
439
- ensure
440
- dirIt.close
441
- end
442
- end
443
- dirIt
444
- end
445
-
446
- def pwd; @mappedZip.pwd; end
447
- alias getwd pwd
448
-
449
- def chdir(aDirectoryName)
450
- unless @file.stat(aDirectoryName).directory?
451
- raise Errno::EINVAL, "Invalid argument - #{aDirectoryName}"
452
- end
453
- @mappedZip.pwd = @file.expand_path(aDirectoryName)
454
- end
455
-
456
- def entries(aDirectoryName)
457
- entries = []
458
- foreach(aDirectoryName) { |e| entries << e }
459
- entries
460
- end
461
-
462
- def foreach(aDirectoryName)
463
- unless @file.stat(aDirectoryName).directory?
464
- raise Errno::ENOTDIR, aDirectoryName
465
- end
466
- path = @file.expand_path(aDirectoryName).ensure_end("/")
467
-
468
- subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$")
469
- @mappedZip.each {
470
- |fileName|
471
- match = subDirEntriesRegex.match(fileName)
472
- yield(match[1]) unless match == nil
473
- }
474
- end
475
-
476
- def delete(entryName)
477
- unless @file.stat(entryName).directory?
478
- raise Errno::EINVAL, "Invalid argument - #{entryName}"
479
- end
480
- @mappedZip.remove(entryName)
481
- end
482
- alias rmdir delete
483
- alias unlink delete
484
-
485
- def mkdir(entryName, permissionInt = 0755)
486
- @mappedZip.mkdir(entryName, permissionInt)
487
- end
488
-
489
- def chroot(*args)
490
- raise NotImplementedError, "The chroot() function is not implemented"
491
- end
492
-
493
- end
494
-
495
- class ZipFsDirIterator # :nodoc:all
496
- include Enumerable
497
-
498
- def initialize(arrayOfFileNames)
499
- @fileNames = arrayOfFileNames
500
- @index = 0
501
- end
502
-
503
- def close
504
- @fileNames = nil
505
- end
506
-
507
- def each(&aProc)
508
- raise IOError, "closed directory" if @fileNames == nil
509
- @fileNames.each(&aProc)
510
- end
511
-
512
- def read
513
- raise IOError, "closed directory" if @fileNames == nil
514
- @fileNames[(@index+=1)-1]
515
- end
516
-
517
- def rewind
518
- raise IOError, "closed directory" if @fileNames == nil
519
- @index = 0
520
- end
521
-
522
- def seek(anIntegerPosition)
523
- raise IOError, "closed directory" if @fileNames == nil
524
- @index = anIntegerPosition
525
- end
526
-
527
- def tell
528
- raise IOError, "closed directory" if @fileNames == nil
529
- @index
530
- end
531
- end
532
-
533
- # All access to ZipFile from ZipFsFile and ZipFsDir goes through a
534
- # ZipFileNameMapper, which has one responsibility: ensure
535
- class ZipFileNameMapper # :nodoc:all
536
- include Enumerable
537
-
538
- def initialize(zipFile)
539
- @zipFile = zipFile
540
- @pwd = "/"
541
- end
542
-
543
- attr_accessor :pwd
544
-
545
- def find_entry(fileName)
546
- @zipFile.find_entry(expand_to_entry(fileName))
547
- end
548
-
549
- def get_entry(fileName)
550
- @zipFile.get_entry(expand_to_entry(fileName))
551
- end
552
-
553
- def get_input_stream(fileName, &aProc)
554
- @zipFile.get_input_stream(expand_to_entry(fileName), &aProc)
555
- end
556
-
557
- def get_output_stream(fileName, &aProc)
558
- @zipFile.get_output_stream(expand_to_entry(fileName), &aProc)
559
- end
560
-
561
- def read(fileName)
562
- @zipFile.read(expand_to_entry(fileName))
563
- end
564
-
565
- def remove(fileName)
566
- @zipFile.remove(expand_to_entry(fileName))
567
- end
568
-
569
- def rename(fileName, newName, &continueOnExistsProc)
570
- @zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),
571
- &continueOnExistsProc)
572
- end
573
-
574
- def mkdir(fileName, permissionInt = 0755)
575
- @zipFile.mkdir(expand_to_entry(fileName), permissionInt)
576
- end
577
-
578
- # Turns entries into strings and adds leading /
579
- # and removes trailing slash on directories
580
- def each
581
- @zipFile.each {
582
- |e|
583
- yield("/"+e.to_s.chomp("/"))
584
- }
585
- end
586
-
587
- def expand_path(aPath)
588
- expanded = aPath.starts_with("/") ? aPath : @pwd.ensure_end("/") + aPath
589
- expanded.gsub!(/\/\.(\/|$)/, "")
590
- expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, "")
591
- expanded.empty? ? "/" : expanded
592
- end
593
-
594
- private
595
-
596
- def expand_to_entry(aPath)
597
- expand_path(aPath).lchop
598
- end
599
- end
600
- end
601
-
602
- class ZipFile
603
- include ZipFileSystem
604
- end
605
- end
606
-
607
- # Copyright (C) 2002, 2003 Thomas Sondergaard
608
- # rubyzip is free software; you can redistribute it and/or
609
- # modify it under the terms of the ruby license.
@@ -1,90 +0,0 @@
1
- # With ziprequire you can load ruby modules from a zip file. This means
2
- # ruby's module include path can include zip-files.
3
- #
4
- # The following example creates a zip file with a single entry
5
- # <code>log/simplelog.rb</code> that contains a single function
6
- # <code>simpleLog</code>:
7
- #
8
- # require 'zip/zipfilesystem'
9
- #
10
- # Zip::ZipFile.open("my.zip", true) {
11
- # |zf|
12
- # zf.file.open("log/simplelog.rb", "w") {
13
- # |f|
14
- # f.puts "def simpleLog(v)"
15
- # f.puts ' Kernel.puts "INFO: #{v}"'
16
- # f.puts "end"
17
- # }
18
- # }
19
- #
20
- # To use the ruby module stored in the zip archive simply require
21
- # <code>zip/ziprequire</code> and include the <code>my.zip</code> zip
22
- # file in the module search path. The following command shows one
23
- # way to do this:
24
- #
25
- # ruby -rzip/ziprequire -Imy.zip -e " require 'log/simplelog'; simpleLog 'Hello world' "
26
-
27
- #$: << 'data/rubycode.zip' << 'data/rubycode2.zip'
28
-
29
-
30
- require 'zip/zip'
31
-
32
- class ZipList #:nodoc:all
33
- def initialize(zipFileList)
34
- @zipFileList = zipFileList
35
- end
36
-
37
- def get_input_stream(entry, &aProc)
38
- @zipFileList.each {
39
- |zfName|
40
- Zip::ZipFile.open(zfName) {
41
- |zf|
42
- begin
43
- return zf.get_input_stream(entry, &aProc)
44
- rescue Errno::ENOENT
45
- end
46
- }
47
- }
48
- raise Errno::ENOENT,
49
- "No matching entry found in zip files '#{@zipFileList.join(', ')}' "+
50
- " for '#{entry}'"
51
- end
52
- end
53
-
54
-
55
- module Kernel #:nodoc:all
56
- alias :oldRequire :require
57
-
58
- def require(moduleName)
59
- zip_require(moduleName) || oldRequire(moduleName)
60
- end
61
-
62
- def zip_require(moduleName)
63
- return false if already_loaded?(moduleName)
64
- get_resource(ensure_rb_extension(moduleName)) {
65
- |zis|
66
- eval(zis.read); $" << moduleName
67
- }
68
- return true
69
- rescue Errno::ENOENT => ex
70
- return false
71
- end
72
-
73
- def get_resource(resourceName, &aProc)
74
- zl = ZipList.new($:.grep(/\.zip$/))
75
- zl.get_input_stream(resourceName, &aProc)
76
- end
77
-
78
- def already_loaded?(moduleName)
79
- moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$")
80
- $".detect { |e| e =~ moduleRE } != nil
81
- end
82
-
83
- def ensure_rb_extension(aString)
84
- aString.sub(/(\.rb)?$/i, ".rb")
85
- end
86
- end
87
-
88
- # Copyright (C) 2002 Thomas Sondergaard
89
- # rubyzip is free software; you can redistribute it and/or
90
- # modify it under the terms of the ruby license.