updated rubyzip from 0.5.8 to 0.9.1 and moved plugin into the right folder

This commit is contained in:
Matthias Tarasiewicz 2007-01-17 12:47:46 +00:00
parent 78ebbed446
commit 692a1beffe
33 changed files with 6743 additions and 123 deletions

1081
vendor/plugins/rubyzip-0.9.1/ChangeLog vendored Normal file

File diff suppressed because it is too large Load diff

144
vendor/plugins/rubyzip-0.9.1/NEWS vendored Normal file
View file

@ -0,0 +1,144 @@
= Version 0.9.1
Added symlink support and support for unix file permissions. Reduced
memory usage during decompression.
New methods ZipFile::[follow_symlinks, restore_times, restore_permissions, restore_ownership].
New methods ZipEntry::unix_perms, ZipInputStream::eof?.
Added documentation and test for new ZipFile::extract.
Added some of the API suggestions from sf.net #1281314.
Applied patch for sf.net bug #1446926.
Applied patch for sf.net bug #1459902.
Rework ZipEntry and delegate classes.
= Version 0.5.12
Fixed problem with writing binary content to a ZipFile in MS Windows.
= Version 0.5.11
Fixed name clash file method copy_stream from fileutils.rb. Fixed
problem with references to constant CHUNK_SIZE.
ZipInputStream/AbstractInputStream read is now buffered like ruby IO's
read method, which means that read and gets etc can be mixed. The
unbuffered read method has been renamed to sysread.
= Version 0.5.10
Fixed method name resolution problem with FileUtils::copy_stream and
IOExtras::copy_stream.
= Version 0.5.9
Fixed serious memory consumption issue
= Version 0.5.8
Fixed install script.
= Version 0.5.7
install.rb no longer assumes it is being run from the toplevel source
dir. Directory structure changed to reflect common ruby library
project structure. Migrated from RubyUnit to Test::Unit format. Now
uses Rake to build source packages and gems and run unit tests.
= Version 0.5.6
Fix for FreeBSD 4.9 which returns Errno::EFBIG instead of
Errno::EINVAL for some invalid seeks. Fixed 'version needed to
extract'-field incorrect in local headers.
= Version 0.5.5
Fix for a problem with writing zip files that concerns only ruby 1.8.1.
= Version 0.5.4
Significantly reduced memory footprint when modifying zip files.
= Version 0.5.3
Added optimization to avoid decompressing and recompressing individual
entries when modifying a zip archive.
= Version 0.5.2
Fixed ZipFile corruption bug in ZipFile class. Added basic unix
extra-field support.
= Version 0.5.1
Fixed ZipFile.get_output_stream bug.
= Version 0.5.0
List of changes:
* Ruby 1.8.0 and ruby-zlib 0.6.0 compatibility
* Changed method names from camelCase to rubys underscore style.
* Installs to zip/ subdir instead of directly to site_ruby
* Added ZipFile.directory and ZipFile.file - each method return an
object that can be used like Dir and File only for the contents of the
zip file.
* Added sample application zipfind which works like Find.find, only
Zip::ZipFind.find traverses into zip archives too.
Bug fixes:
* AbstractInputStream.each_line with non-default separator
= Version 0.5.0a
Source reorganized. Added ziprequire, which can be used to load ruby
modules from a zip file, in a fashion similar to jar files in
Java. Added gtkRubyzip, another sample application. Implemented
ZipInputStream.lineno and ZipInputStream.rewind
Bug fixes:
* Read and write date and time information correctly for zip entries.
* Fixed read() using separate buffer, causing mix of gets/readline/read to
cause problems.
= Version 0.4.2
Performance optimizations. Test suite runs in half the time.
= Version 0.4.1
Windows compatibility fixes.
= Version 0.4.0
Zip::ZipFile is now mutable and provides a more convenient way of
modifying zip archives than Zip::ZipOutputStream. Operations for
adding, extracting, renaming, replacing and removing entries to zip
archives are now available.
Runs without warnings with -w switch.
Install script install.rb added.
= Version 0.3.1
Rudimentary support for writing zip archives.
= Version 0.2.2
Fixed and extended unit test suite. Updated to work with ruby/zlib
0.5. It doesn't work with earlier versions of ruby/zlib.
= Version 0.2.0
Class ZipFile added. Where ZipInputStream is used to read the
individual entries in a zip file, ZipFile reads the central directory
in the zip archive, so you can get to any entry in the zip archive
without having to skipping through all the preceeding entries.
= Version 0.1.0
First working version of ZipInputStream.

72
vendor/plugins/rubyzip-0.9.1/README vendored Normal file
View file

@ -0,0 +1,72 @@
= rubyzip
rubyzip is a ruby library for reading and writing zip files.
= Install
If you have rubygems you can install rubyzip directly from the gem
repository
gem install rubyzip
Otherwise obtain the source (see below) and run
ruby install.rb
To run the unit tests you need to have test::unit installed
rake test
= Documentation
There is more than one way to access or create a zip archive with
rubyzip. The basic API is modeled after the classes in
java.util.zip from the Java SDK. This means there are classes such
as Zip::ZipInputStream, Zip::ZipOutputStream and
Zip::ZipFile. Zip::ZipInputStream provides a basic interface for
iterating through the entries in a zip archive and reading from the
entries in the same way as from a regular File or IO
object. ZipOutputStream is the corresponding basic output
facility. Zip::ZipFile provides a mean for accessing the archives
central directory and provides means for accessing any entry without
having to iterate through the archive. Unlike Java's
java.util.zip.ZipFile rubyzip's Zip::ZipFile is mutable, which means
it can be used to change zip files as well.
Another way to access a zip archive with rubyzip is to use rubyzip's
Zip::ZipFileSystem API. Using this API files can be read from and
written to the archive in much the same manner as ruby's builtin
classes allows files to be read from and written to the file system.
rubyzip also features the
zip/ziprequire.rb[link:files/lib/zip/ziprequire_rb.html] module which
allows ruby to load ruby modules from zip archives.
For details about the specific behaviour of classes and methods refer
to the test suite. Finally you can generate the rdoc documentation or
visit http://rubyzip.sourceforge.net.
= License
rubyzip is distributed under the same license as ruby. See
http://www.ruby-lang.org/en/LICENSE.txt
= Website and Project Home
http://rubyzip.sourceforge.net
http://sourceforge.net/projects/rubyzip
== Download (tarballs and gems)
http://sourceforge.net/project/showfiles.php?group_id=43107&package_id=35377
= Authors
Thomas Sondergaard (thomas at sondergaard.cc)
Technorama Ltd. (oss-ruby-zip at technorama.net)
extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)

110
vendor/plugins/rubyzip-0.9.1/Rakefile vendored Executable file
View file

@ -0,0 +1,110 @@
# Rakefile for RubyGems -*- ruby -*-
require 'rubygems'
require 'rake/clean'
require 'rake/testtask'
require 'rake/packagetask'
require 'rake/gempackagetask'
require 'rake/rdoctask'
require 'rake/contrib/sshpublisher'
require 'net/ftp'
PKG_NAME = 'rubyzip'
PKG_VERSION = File.read('lib/zip/zip.rb').match(/\s+VERSION\s*=\s*'(.*)'/)[1]
PKG_FILES = FileList.new
PKG_FILES.add %w{ README NEWS TODO ChangeLog install.rb Rakefile }
PKG_FILES.add %w{ samples/*.rb }
PKG_FILES.add %w{ test/*.rb }
PKG_FILES.add %w{ test/data/* }
PKG_FILES.exclude "test/data/generated"
PKG_FILES.add %w{ lib/**/*.rb }
def clobberFromCvsIgnore(path)
CLOBBER.add File.readlines(path+'/.cvsignore').map {
|f| File.join(path, f.chomp)
} rescue StandardError
end
clobberFromCvsIgnore '.'
clobberFromCvsIgnore 'samples'
clobberFromCvsIgnore 'test'
clobberFromCvsIgnore 'test/data'
task :default => [:test]
desc "Run unit tests"
task :test do
ruby %{-C test alltests.rb}
end
# Shortcuts for test targets
task :ut => [:test]
spec = Gem::Specification.new do |s|
s.name = PKG_NAME
s.version = PKG_VERSION
s.author = "Thomas Sondergaard"
s.email = "thomas(at)sondergaard.cc"
s.homepage = "http://rubyzip.sourceforge.net/"
s.platform = Gem::Platform::RUBY
s.summary = "rubyzip is a ruby module for reading and writing zip files"
s.files = PKG_FILES.to_a
s.require_path = 'lib'
end
Rake::GemPackageTask.new(spec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
end
Rake::RDocTask.new do |rd|
rd.main = "README"
rd.rdoc_files.add %W{ lib/zip/*.rb README NEWS TODO ChangeLog }
rd.options << "--title 'rubyzip documentation' --webcvs http://cvs.sourceforge.net/viewcvs.py/rubyzip/rubyzip/"
# rd.options << "--all"
end
desc "Publish documentation"
task :pdoc => [:rdoc] do
Rake::SshFreshDirPublisher.
new("thomas@rubyzip.sourceforge.net", "/home/groups/r/ru/rubyzip/htdocs", "html").upload
end
desc "Publish package"
task :ppackage => [:package] do
Net::FTP.open("upload.sourceforge.net",
"ftp",
ENV['USER']+"@"+ENV['HOSTNAME']) {
|ftpclient|
ftpclient.passive = true
ftpclient.chdir "incoming"
Dir['pkg/*.{tgz,zip,gem}'].each {
|e|
ftpclient.putbinaryfile(e, File.basename(e))
}
}
end
desc "Generate the ChangeLog file"
task :ChangeLog do
puts "Updating ChangeLog"
system %{cvs2cl}
end
desc "Make a release"
task :release => [:tag_release, :pdoc, :ppackage] do
end
desc "Make a release tag"
task :tag_release do
tag = "release-#{PKG_VERSION.gsub('.','-')}"
puts "Checking for tag '#{tag}'"
if (Regexp.new("^\\s+#{tag}") =~ `cvs log README`)
abort "Tag '#{tag}' already exists"
end
puts "Tagging module with '#{tag}'"
system("cvs tag #{tag}")
end

16
vendor/plugins/rubyzip-0.9.1/TODO vendored Normal file
View file

@ -0,0 +1,16 @@
* ZipInputStream: Support zip-files with trailing data descriptors
* Adjust rdoc stylesheet to advertise inherited methods if possible
* Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
* Suggestion: ZipFile#extract destination should default to "."
* Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
* SUggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
* (is buffering used anywhere with write?)
* Inflater.sysread should pass the buffer to produce_input.
* Implement ZipFsDir.glob
* ZipFile.checkIntegrity method
* non-MSDOS permission attributes
** See mail from Ned Konz to ruby-talk subj. "Re: SV: [ANN] Archive 0.2"
* Packager version, required unpacker version in zip headers
** See mail from Ned Konz to ruby-talk subj. "Re: SV: [ANN] Archive 0.2"
* implement storing attributes and ownership information

22
vendor/plugins/rubyzip-0.9.1/install.rb vendored Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env ruby
$VERBOSE = true
require 'rbconfig'
require 'find'
require 'ftools'
include Config
files = %w{ stdrubyext.rb ioextras.rb zip.rb zipfilesystem.rb ziprequire.rb tempfile_bugfixed.rb }
INSTALL_DIR = File.join(CONFIG["sitelibdir"], "zip")
File.makedirs(INSTALL_DIR)
SOURCE_DIR = File.join(File.dirname($0), "lib/zip")
files.each {
|filename|
installPath = File.join(INSTALL_DIR, filename)
File::install(File.join(SOURCE_DIR, filename), installPath, 0644, true)
}

View file

@ -1,5 +1,15 @@
module IOExtras #:nodoc: module IOExtras #:nodoc:
CHUNK_SIZE = 32768
RANGE_ALL = 0..-1
def self.copy_stream(ostream, istream)
s = ''
ostream.write(istream.read(CHUNK_SIZE, s)) until istream.eof?
end
# Implements kind_of? in order to pretend to be an IO object # Implements kind_of? in order to pretend to be an IO object
module FakeIO module FakeIO
def kind_of?(object) def kind_of?(object)
@ -22,6 +32,34 @@ module IOExtras #:nodoc:
attr_accessor :lineno attr_accessor :lineno
def read(numberOfBytes = nil, buf = nil)
tbuf = nil
if @outputBuffer.length > 0
if numberOfBytes <= @outputBuffer.length
tbuf = @outputBuffer.slice!(0, numberOfBytes)
else
numberOfBytes -= @outputBuffer.length if (numberOfBytes)
rbuf = sysread(numberOfBytes, buf)
tbuf = @outputBuffer
tbuf << rbuf if (rbuf)
@outputBuffer = ""
end
else
tbuf = sysread(numberOfBytes, buf)
end
return nil unless (tbuf)
if buf
buf.replace(tbuf)
else
buf = tbuf
end
buf
end
def readlines(aSepString = $/) def readlines(aSepString = $/)
retVal = [] retVal = []
each_line(aSepString) { |line| retVal << line } each_line(aSepString) { |line| retVal << line }

View file

540
lib/zip/zip.rb → vendor/plugins/rubyzip-0.9.1/lib/zip/zip.rb vendored Normal file → Executable file
View file

@ -2,6 +2,7 @@ require 'delegate'
require 'singleton' require 'singleton'
require 'tempfile' require 'tempfile'
require 'ftools' require 'ftools'
require 'stringio'
require 'zlib' require 'zlib'
require 'zip/stdrubyext' require 'zip/stdrubyext'
require 'zip/ioextras' require 'zip/ioextras'
@ -19,10 +20,12 @@ end
module Zip module Zip
VERSION = '0.5.8' VERSION = '0.9.1'
RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i
RUNNING_ON_WINDOWS = /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
# Ruby 1.7.x compatibility # Ruby 1.7.x compatibility
# In ruby 1.6.x and 1.8.0 reading from an empty stream returns # In ruby 1.6.x and 1.8.0 reading from an empty stream returns
# an empty string the first time and then nil. # an empty string the first time and then nil.
@ -104,9 +107,10 @@ module Zip
# method on a newly created ZipInputStream before reading from # method on a newly created ZipInputStream before reading from
# the first entry in the archive. Returns nil when there are # the first entry in the archive. Returns nil when there are
# no more entries. # no more entries.
def get_next_entry def get_next_entry
@archiveIO.seek(@currentEntry.next_header_offset, @archiveIO.seek(@currentEntry.next_header_offset,
IO::SEEK_SET) if @currentEntry IO::SEEK_SET) if @currentEntry
open_entry open_entry
end end
@ -119,11 +123,16 @@ module Zip
open_entry open_entry
end end
# Modeled after IO.read # Modeled after IO.sysread
def read(numberOfBytes = nil) def sysread(numberOfBytes = nil, buf = nil)
@decompressor.read(numberOfBytes) @decompressor.sysread(numberOfBytes, buf)
end end
def eof
@outputBuffer.empty? && @decompressor.eof
end
alias :eof? :eof
protected protected
def open_entry def open_entry
@ -170,11 +179,11 @@ module Zip
@hasReturnedEmptyString = ! EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST @hasReturnedEmptyString = ! EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST
end end
def read(numberOfBytes = nil) def sysread(numberOfBytes = nil, buf = nil)
readEverything = (numberOfBytes == nil) readEverything = (numberOfBytes == nil)
while (readEverything || @outputBuffer.length < numberOfBytes) while (readEverything || @outputBuffer.length < numberOfBytes)
break if internal_input_finished? break if internal_input_finished?
@outputBuffer << internal_produce_input @outputBuffer << internal_produce_input(buf)
end end
return value_when_finished if @outputBuffer.length==0 && input_finished? return value_when_finished if @outputBuffer.length==0 && input_finished?
endIndex= numberOfBytes==nil ? @outputBuffer.length : numberOfBytes endIndex= numberOfBytes==nil ? @outputBuffer.length : numberOfBytes
@ -190,14 +199,24 @@ module Zip
end end
# to be used with produce_input, not read (as read may still have more data cached) # to be used with produce_input, not read (as read may still have more data cached)
# is data cached anywhere other than @outputBuffer? the comment above may be wrong
def input_finished? def input_finished?
@outputBuffer.empty? && internal_input_finished? @outputBuffer.empty? && internal_input_finished?
end end
alias :eof :input_finished?
alias :eof? :input_finished?
private private
def internal_produce_input def internal_produce_input(buf = nil)
@zlibInflater.inflate(@inputStream.read(Decompressor::CHUNK_SIZE)) retried = 0
begin
@zlibInflater.inflate(@inputStream.read(Decompressor::CHUNK_SIZE, buf))
rescue Zlib::BufError
raise if (retried >= 5) # how many times should we retry?
retried += 1
retry
end
end end
def internal_input_finished? def internal_input_finished?
@ -221,7 +240,7 @@ module Zip
end end
# TODO: Specialize to handle different behaviour in ruby > 1.7.0 ? # TODO: Specialize to handle different behaviour in ruby > 1.7.0 ?
def read(numberOfBytes = nil) def sysread(numberOfBytes = nil, buf = nil)
if input_finished? if input_finished?
hasReturnedEmptyStringVal=@hasReturnedEmptyString hasReturnedEmptyStringVal=@hasReturnedEmptyString
@hasReturnedEmptyString=true @hasReturnedEmptyString=true
@ -233,21 +252,23 @@ module Zip
numberOfBytes = @charsToRead-@readSoFar numberOfBytes = @charsToRead-@readSoFar
end end
@readSoFar += numberOfBytes @readSoFar += numberOfBytes
@inputStream.read(numberOfBytes) @inputStream.read(numberOfBytes, buf)
end end
def produce_input def produce_input
read(Decompressor::CHUNK_SIZE) sysread(Decompressor::CHUNK_SIZE)
end end
def input_finished? def input_finished?
(@readSoFar >= @charsToRead) (@readSoFar >= @charsToRead)
end end
alias :eof :input_finished?
alias :eof? :input_finished?
end end
class NullDecompressor #:nodoc:all class NullDecompressor #:nodoc:all
include Singleton include Singleton
def read(numberOfBytes = nil) def sysread(numberOfBytes = nil, buf = nil)
nil nil
end end
@ -258,6 +279,11 @@ module Zip
def input_finished? def input_finished?
true true
end end
def eof
true
end
alias :eof? :eof
end end
class NullInputStream < NullDecompressor #:nodoc:all class NullInputStream < NullDecompressor #:nodoc:all
@ -268,8 +294,60 @@ module Zip
STORED = 0 STORED = 0
DEFLATED = 8 DEFLATED = 8
FSTYPE_FAT = 0
FSTYPE_AMIGA = 1
FSTYPE_VMS = 2
FSTYPE_UNIX = 3
FSTYPE_VM_CMS = 4
FSTYPE_ATARI = 5
FSTYPE_HPFS = 6
FSTYPE_MAC = 7
FSTYPE_Z_SYSTEM = 8
FSTYPE_CPM = 9
FSTYPE_TOPS20 = 10
FSTYPE_NTFS = 11
FSTYPE_QDOS = 12
FSTYPE_ACORN = 13
FSTYPE_VFAT = 14
FSTYPE_MVS = 15
FSTYPE_BEOS = 16
FSTYPE_TANDEM = 17
FSTYPE_THEOS = 18
FSTYPE_MAC_OSX = 19
FSTYPE_ATHEOS = 30
FSTYPES = {
FSTYPE_FAT => 'FAT'.freeze,
FSTYPE_AMIGA => 'Amiga'.freeze,
FSTYPE_VMS => 'VMS (Vax or Alpha AXP)'.freeze,
FSTYPE_UNIX => 'Unix'.freeze,
FSTYPE_VM_CMS => 'VM/CMS'.freeze,
FSTYPE_ATARI => 'Atari ST'.freeze,
FSTYPE_HPFS => 'OS/2 or NT HPFS'.freeze,
FSTYPE_MAC => 'Macintosh'.freeze,
FSTYPE_Z_SYSTEM => 'Z-System'.freeze,
FSTYPE_CPM => 'CP/M'.freeze,
FSTYPE_TOPS20 => 'TOPS-20'.freeze,
FSTYPE_NTFS => 'NTFS'.freeze,
FSTYPE_QDOS => 'SMS/QDOS'.freeze,
FSTYPE_ACORN => 'Acorn RISC OS'.freeze,
FSTYPE_VFAT => 'Win32 VFAT'.freeze,
FSTYPE_MVS => 'MVS'.freeze,
FSTYPE_BEOS => 'BeOS'.freeze,
FSTYPE_TANDEM => 'Tandem NSK'.freeze,
FSTYPE_THEOS => 'Theos'.freeze,
FSTYPE_MAC_OSX => 'Mac OS/X (Darwin)'.freeze,
FSTYPE_ATHEOS => 'AtheOS'.freeze,
}.freeze
attr_accessor :comment, :compressed_size, :crc, :extra, :compression_method, attr_accessor :comment, :compressed_size, :crc, :extra, :compression_method,
:name, :size, :localHeaderOffset, :zipfile, :fstype, :externalFileAttributes :name, :size, :localHeaderOffset, :zipfile, :fstype, :externalFileAttributes, :gp_flags, :header_signature
attr_accessor :follow_symlinks
attr_accessor :restore_times, :restore_permissions, :restore_ownership
attr_accessor :unix_uid, :unix_gid, :unix_perms
attr_reader :ftype, :filepath # :nodoc:
def initialize(zipfile = "", name = "", comment = "", extra = "", def initialize(zipfile = "", name = "", comment = "", extra = "",
compressed_size = 0, crc = 0, compressed_size = 0, crc = 0,
@ -283,11 +361,37 @@ module Zip
@internalFileAttributes = 1 @internalFileAttributes = 1
@externalFileAttributes = 0 @externalFileAttributes = 0
@version = 52 # this library's version @version = 52 # this library's version
@fstype = 0 # default is fat @ftype = nil # unspecified or unknown
@filepath = nil
if Zip::RUNNING_ON_WINDOWS
@fstype = FSTYPE_FAT
else
@fstype = FSTYPE_UNIX
end
@zipfile, @comment, @compressed_size, @crc, @extra, @compression_method, @zipfile, @comment, @compressed_size, @crc, @extra, @compression_method,
@name, @size = zipfile, comment, compressed_size, crc, @name, @size = zipfile, comment, compressed_size, crc,
extra, compression_method, name, size extra, compression_method, name, size
@time = time @time = time
@follow_symlinks = false
@restore_times = true
@restore_permissions = false
@restore_ownership = false
# BUG: need an extra field to support uid/gid's
@unix_uid = nil
@unix_gid = nil
@unix_perms = nil
# @posix_acl = nil
# @ntfs_acl = nil
if name_is_directory?
@ftype = :directory
else
@ftype = :file
end
unless ZipExtraField === @extra unless ZipExtraField === @extra
@extra = ZipExtraField.new(@extra.to_s) @extra = ZipExtraField.new(@extra.to_s)
end end
@ -312,13 +416,27 @@ module Zip
@time = aTime @time = aTime
end end
# Returns +true+ if the entry is a directory.
def directory? def directory?
return (%r{\/$} =~ @name) != nil raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
@ftype == :directory
end end
alias :is_directory :directory? alias :is_directory :directory?
# Returns +true+ if the entry is a file.
def file? def file?
! directory? raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
@ftype == :file
end
# Returns +true+ if the entry is a symlink.
def symlink?
raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
@ftype == :link
end
def name_is_directory? #:nodoc:all
(%r{\/$} =~ @name) != nil
end end
def local_entry_offset #:nodoc:all def local_entry_offset #:nodoc:all
@ -338,23 +456,41 @@ module Zip
local_entry_offset + self.compressed_size local_entry_offset + self.compressed_size
end end
# Extracts entry to file destPath (defaults to @name).
def extract(destPath = @name, &onExistsProc)
onExistsProc ||= proc { false }
if directory?
create_directory(destPath, &onExistsProc)
elsif file?
write_file(destPath, &onExistsProc)
elsif symlink?
create_symlink(destPath, &onExistsProc)
else
raise RuntimeError, "unknown file type #{self.inspect}"
end
self
end
def to_s def to_s
@name @name
end end
protected protected
def ZipEntry.read_zip_short(io) def ZipEntry.read_zip_short(io) # :nodoc:
io.read(2).unpack('v')[0] io.read(2).unpack('v')[0]
end end
def ZipEntry.read_zip_long(io) def ZipEntry.read_zip_long(io) # :nodoc:
io.read(4).unpack('V')[0] io.read(4).unpack('V')[0]
end end
public public
LOCAL_ENTRY_SIGNATURE = 0x04034b50 LOCAL_ENTRY_SIGNATURE = 0x04034b50
LOCAL_ENTRY_STATIC_HEADER_LENGTH = 30 LOCAL_ENTRY_STATIC_HEADER_LENGTH = 30
LOCAL_ENTRY_TRAILING_DESCRIPTOR_LENGTH = 4+4+4
def read_local_entry(io) #:nodoc:all def read_local_entry(io) #:nodoc:all
@localHeaderOffset = io.tell @localHeaderOffset = io.tell
@ -363,10 +499,10 @@ module Zip
raise ZipError, "Premature end of file. Not enough data for zip entry local header" raise ZipError, "Premature end of file. Not enough data for zip entry local header"
end end
localHeader , @header_signature ,
@version , @version ,
@fstype , @fstype ,
@gpFlags , @gp_flags ,
@compression_method, @compression_method,
lastModTime , lastModTime ,
lastModDate , lastModDate ,
@ -376,7 +512,7 @@ module Zip
nameLength , nameLength ,
extraLength = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv') extraLength = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv')
unless (localHeader == LOCAL_ENTRY_SIGNATURE) unless (@header_signature == LOCAL_ENTRY_SIGNATURE)
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'" raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
end end
set_time(lastModDate, lastModTime) set_time(lastModDate, lastModTime)
@ -409,7 +545,7 @@ module Zip
io << io <<
[LOCAL_ENTRY_SIGNATURE , [LOCAL_ENTRY_SIGNATURE ,
0 , 0 ,
0 , # @gpFlags , 0 , # @gp_flags ,
@compression_method , @compression_method ,
@time.to_binary_dos_time , # @lastModTime , @time.to_binary_dos_time , # @lastModTime ,
@time.to_binary_dos_date , # @lastModDate , @time.to_binary_dos_date , # @lastModDate ,
@ -431,11 +567,11 @@ module Zip
raise ZipError, "Premature end of file. Not enough data for zip cdir entry header" raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
end end
cdirSignature , @header_signature ,
@version , # version of encoding software @version , # version of encoding software
@fstype , # filesystem type @fstype , # filesystem type
@versionNeededToExtract, @versionNeededToExtract,
@gpFlags , @gp_flags ,
@compression_method , @compression_method ,
lastModTime , lastModTime ,
lastModDate , lastModDate ,
@ -453,7 +589,7 @@ module Zip
@extra , @extra ,
@comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV') @comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')
unless (cdirSignature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE) unless (@header_signature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'" raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
end end
set_time(lastModDate, lastModTime) set_time(lastModDate, lastModTime)
@ -468,6 +604,28 @@ module Zip
unless (@comment && @comment.length == commentLength) unless (@comment && @comment.length == commentLength)
raise ZipError, "Truncated cdir zip entry header" raise ZipError, "Truncated cdir zip entry header"
end end
case @fstype
when FSTYPE_UNIX
@unix_perms = (@externalFileAttributes >> 16) & 07777
case (@externalFileAttributes >> 28)
when 04
@ftype = :directory
when 010
@ftype = :file
when 012
@ftype = :link
else
raise ZipInternalError, "unknown file type #{'0%o' % (@externalFileAttributes >> 28)}"
end
else
if name_is_directory?
@ftype = :directory
else
@ftype = :file
end
end
end end
def ZipEntry.read_c_dir_entry(io) #:nodoc:all def ZipEntry.read_c_dir_entry(io) #:nodoc:all
@ -478,14 +636,65 @@ module Zip
return nil return nil
end end
def file_stat(path) # :nodoc:
if @follow_symlinks
return File::stat(path)
else
return File::lstat(path)
end
end
def get_extra_attributes_from_path(path) # :nodoc:
unless Zip::RUNNING_ON_WINDOWS
stat = file_stat(path)
@unix_uid = stat.uid
@unix_gid = stat.gid
@unix_perms = stat.mode & 07777
end
end
def set_extra_attributes_on_path(destPath) # :nodoc:
return unless (file? or directory?)
case @fstype
when FSTYPE_UNIX
# BUG: does not update timestamps into account
# ignore setuid/setgid bits by default. honor if @restore_ownership
unix_perms_mask = 01777
unix_perms_mask = 07777 if (@restore_ownership)
File::chmod(@unix_perms & unix_perms_mask, destPath) if (@restore_permissions && @unix_perms)
File::chown(@unix_uid, @unix_gid, destPath) if (@restore_ownership && @unix_uid && @unix_gid && Process::egid == 0)
# File::utimes()
end
end
def write_c_dir_entry(io) #:nodoc:all def write_c_dir_entry(io) #:nodoc:all
case @fstype
when FSTYPE_UNIX
ft = nil
case @ftype
when :file
ft = 010
@unix_perms ||= 0644
when :directory
ft = 004
@unix_perms ||= 0755
when :symlink
ft = 012
@unix_perms ||= 0755
else
raise ZipInternalError, "unknown file type #{self.inspect}"
end
@externalFileAttributes = (ft << 12 | (@unix_perms & 07777)) << 16
end
io << io <<
[CENTRAL_DIRECTORY_ENTRY_SIGNATURE, [CENTRAL_DIRECTORY_ENTRY_SIGNATURE,
@version , # version of encoding software @version , # version of encoding software
@fstype , # filesystem type @fstype , # filesystem type
0 , # @versionNeededToExtract , 0 , # @versionNeededToExtract ,
0 , # @gpFlags , 0 , # @gp_flags ,
@compression_method , @compression_method ,
@time.to_binary_dos_time , # @lastModTime , @time.to_binary_dos_time , # @lastModTime ,
@time.to_binary_dos_date , # @lastModDate , @time.to_binary_dos_date , # @lastModDate ,
@ -509,14 +718,15 @@ module Zip
end end
def == (other) def == (other)
return false unless other.class == ZipEntry return false unless other.class == self.class
# Compares contents of local entry and exposed fields # Compares contents of local entry and exposed fields
(@compression_method == other.compression_method && (@compression_method == other.compression_method &&
@crc == other.crc && @crc == other.crc &&
@compressed_size == other.compressed_size && @compressed_size == other.compressed_size &&
@size == other.size && @size == other.size &&
@name == other.name && @name == other.name &&
@extra == other.extra && @extra == other.extra &&
@filepath == other.filepath &&
self.time.dos_equals(other.time)) self.time.dos_equals(other.time))
end end
@ -524,23 +734,79 @@ module Zip
return to_s <=> other.to_s return to_s <=> other.to_s
end end
def get_input_stream # Returns an IO like object for the given ZipEntry.
zis = ZipInputStream.new(@zipfile, localHeaderOffset) # Warning: may behave weird with symlinks.
zis.get_next_entry def get_input_stream(&aProc)
if block_given? if @ftype == :directory
begin return yield(NullInputStream.instance) if block_given?
return yield(zis) return NullInputStream.instance
ensure elsif @filepath
zis.close case @ftype
end when :file
return File.open(@filepath, "rb", &aProc)
when :symlink
linkpath = File::readlink(@filepath)
stringio = StringIO.new(linkpath)
return yield(stringio) if block_given?
return stringio
else
raise "unknown @ftype #{@ftype}"
end
else else
return zis zis = ZipInputStream.new(@zipfile, localHeaderOffset)
zis.get_next_entry
if block_given?
begin
return yield(zis)
ensure
zis.close
end
else
return zis
end
end end
end end
def gather_fileinfo_from_srcpath(srcPath) # :nodoc:
stat = file_stat(srcPath)
case stat.ftype
when 'file'
if name_is_directory?
raise ArgumentError,
"entry name '#{newEntry}' indicates directory entry, but "+
"'#{srcPath}' is not a directory"
end
@ftype = :file
when 'directory'
if ! name_is_directory?
@name += "/"
end
@ftype = :directory
when 'link'
if name_is_directory?
raise ArgumentError,
"entry name '#{newEntry}' indicates directory entry, but "+
"'#{srcPath}' is not a directory"
end
@ftype = :symlink
else
raise RuntimeError, "unknown file type: #{srcPath.inspect} #{stat.inspect}"
end
@filepath = srcPath
get_extra_attributes_from_path(@filepath)
end
def write_to_zip_output_stream(aZipOutputStream) #:nodoc:all def write_to_zip_output_stream(aZipOutputStream) #:nodoc:all
aZipOutputStream.copy_raw_entry(self) if @ftype == :directory
aZipOutputStream.put_next_entry(self)
elsif @filepath
aZipOutputStream.put_next_entry(self)
get_input_stream { |is| IOExtras.copy_stream(aZipOutputStream, is) }
else
aZipOutputStream.copy_raw_entry(self)
end
end end
def parent_as_string def parent_as_string
@ -554,11 +820,75 @@ module Zip
end end
private private
def set_time(binaryDosDate, binaryDosTime) def set_time(binaryDosDate, binaryDosTime)
@time = Time.parse_binary_dos_format(binaryDosDate, binaryDosTime) @time = Time.parse_binary_dos_format(binaryDosDate, binaryDosTime)
rescue ArgumentError rescue ArgumentError
puts "Invalid date/time in zip entry" puts "Invalid date/time in zip entry"
end end
def write_file(destPath, continueOnExistsProc = proc { false })
if File.exists?(destPath) && ! yield(self, destPath)
raise ZipDestinationFileExistsError,
"Destination '#{destPath}' already exists"
end
File.open(destPath, "wb") do |os|
get_input_stream do |is|
set_extra_attributes_on_path(destPath)
buf = ''
while buf = is.sysread(Decompressor::CHUNK_SIZE, buf)
os << buf
end
end
end
end
def create_directory(destPath)
if File.directory? destPath
return
elsif File.exists? destPath
if block_given? && yield(self, destPath)
File.rm_f destPath
else
raise ZipDestinationFileExistsError,
"Cannot create directory '#{destPath}'. "+
"A file already exists with that name"
end
end
Dir.mkdir destPath
set_extra_attributes_on_path(destPath)
end
# BUG: create_symlink() does not use &onExistsProc
def create_symlink(destPath)
stat = nil
begin
stat = File::lstat(destPath)
rescue Errno::ENOENT
end
io = get_input_stream
linkto = io.read
if stat
if stat.symlink?
if File::readlink(destPath) == linkto
return
else
raise ZipDestinationFileExistsError,
"Cannot create symlink '#{destPath}'. "+
"A symlink already exists with that name"
end
else
raise ZipDestinationFileExistsError,
"Cannot create symlink '#{destPath}'. "+
"A file already exists with that name"
end
end
File::symlink(linkto, destPath)
end
end end
@ -624,7 +954,7 @@ module Zip
def put_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION) def put_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION)
raise ZipError, "zip stream is closed" if @closed raise ZipError, "zip stream is closed" if @closed
newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@fileName, entry.to_s) newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@fileName, entry.to_s)
init_next_entry(newEntry) init_next_entry(newEntry, level)
@currentEntry=newEntry @currentEntry=newEntry
end end
@ -811,6 +1141,13 @@ module Zip
@entrySet[entry.parent_as_string] @entrySet[entry.parent_as_string]
end end
def glob(pattern, flags = File::FNM_PATHNAME|File::FNM_DOTMATCH)
entries.select {
|entry|
File.fnmatch(pattern, entry.name.chomp('/'), flags)
}
end
#TODO attr_accessor :auto_create_directories #TODO attr_accessor :auto_create_directories
protected protected
attr_accessor :entrySet attr_accessor :entrySet
@ -898,10 +1235,23 @@ module Zip
io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END) io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END)
rescue Errno::EINVAL rescue Errno::EINVAL
io.seek(0, IO::SEEK_SET) io.seek(0, IO::SEEK_SET)
rescue Errno::EFBIG # FreeBSD 4.9 returns Errno::EFBIG instead of Errno::EINVAL rescue Errno::EFBIG # FreeBSD 4.9 raise Errno::EFBIG instead of Errno::EINVAL
io.seek(0, IO::SEEK_SET) io.seek(0, IO::SEEK_SET)
end end
buf = io.read
# 'buf = io.read' substituted with lump of code to work around FreeBSD 4.5 issue
retried = false
buf = nil
begin
buf = io.read
rescue Errno::EFBIG # FreeBSD 4.5 may raise Errno::EFBIG
raise if (retried)
retried = true
io.seek(0, IO::SEEK_SET)
retry
end
sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V')) sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V'))
raise ZipError, "Zip end of central directory signature not found" unless sigIndex raise ZipError, "Zip end of central directory signature not found" unless sigIndex
buf=buf.slice!((sigIndex+4)...(buf.size)) buf=buf.slice!((sigIndex+4)...(buf.size))
@ -943,6 +1293,7 @@ module Zip
class ZipDestinationFileExistsError < ZipError; end class ZipDestinationFileExistsError < ZipError; end
class ZipCompressionMethodError < ZipError; end class ZipCompressionMethodError < ZipError; end
class ZipEntryNameError < ZipError; end class ZipEntryNameError < ZipError; end
class ZipInternalError < ZipError; end
# ZipFile is modeled after java.util.zip.ZipFile from the Java SDK. # ZipFile is modeled after java.util.zip.ZipFile from the Java SDK.
# The most important methods are those inherited from # The most important methods are those inherited from
@ -993,6 +1344,13 @@ module Zip
attr_reader :name attr_reader :name
# default -> false
attr_accessor :restore_ownership
# default -> false
attr_accessor :restore_permissions
# default -> true
attr_accessor :restore_times
# Opens a zip archive. Pass true as the second parameter to create # Opens a zip archive. Pass true as the second parameter to create
# a new archive if it doesn't exist already. # a new archive if it doesn't exist already.
def initialize(fileName, create = nil) def initialize(fileName, create = nil)
@ -1008,6 +1366,10 @@ module Zip
end end
@create = create @create = create
@storedEntries = @entrySet.dup @storedEntries = @entrySet.dup
@restore_ownership = false
@restore_permissions = false
@restore_times = true
end end
# Same as #new. If a block is passed the ZipFile object is passed # Same as #new. If a block is passed the ZipFile object is passed
@ -1078,11 +1440,8 @@ module Zip
continueOnExistsProc ||= proc { false } continueOnExistsProc ||= proc { false }
check_entry_exists(entry, continueOnExistsProc, "add") check_entry_exists(entry, continueOnExistsProc, "add")
newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@name, entry.to_s) newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@name, entry.to_s)
if is_directory(newEntry, srcPath) newEntry.gather_fileinfo_from_srcpath(srcPath)
@entrySet << ZipStreamableDirectory.new(newEntry) @entrySet << newEntry
else
@entrySet << ZipStreamableFile.new(newEntry, srcPath)
end
end end
# Removes the specified entry. # Removes the specified entry.
@ -1108,11 +1467,7 @@ module Zip
def extract(entry, destPath, &onExistsProc) def extract(entry, destPath, &onExistsProc)
onExistsProc ||= proc { false } onExistsProc ||= proc { false }
foundEntry = get_entry(entry) foundEntry = get_entry(entry)
if foundEntry.is_directory foundEntry.extract(destPath, &onExistsProc)
create_directory(foundEntry, destPath, &onExistsProc)
else
write_file(foundEntry, destPath, &onExistsProc)
end
end end
# Commits changes that has been made since the previous commit to # Commits changes that has been made since the previous commit to
@ -1159,34 +1514,23 @@ module Zip
unless selectedEntry unless selectedEntry
raise Errno::ENOENT, entry raise Errno::ENOENT, entry
end end
selectedEntry.restore_ownership = @restore_ownership
selectedEntry.restore_permissions = @restore_permissions
selectedEntry.restore_times = @restore_times
return selectedEntry return selectedEntry
end end
# Creates a directory # Creates a directory
def mkdir(entryName, permissionInt = 0) #permissionInt ignored def mkdir(entryName, permissionInt = 0755)
if find_entry(entryName) if find_entry(entryName)
raise Errno::EEXIST, "File exists - #{entryName}" raise Errno::EEXIST, "File exists - #{entryName}"
end end
@entrySet << ZipStreamableDirectory.new(ZipEntry.new(name, entryName.to_s.ensure_end("/"))) @entrySet << ZipStreamableDirectory.new(@name, entryName.to_s.ensure_end("/"), nil, permissionInt)
end end
private private
def create_directory(entry, destPath)
if File.directory? destPath
return
elsif File.exists? destPath
if block_given? && yield(entry, destPath)
File.rm_f destPath
else
raise ZipDestinationFileExistsError,
"Cannot create directory '#{destPath}'. "+
"A file already exists with that name"
end
end
Dir.mkdir destPath
end
def is_directory(newEntry, srcPath) def is_directory(newEntry, srcPath)
srcPathIsDirectory = File.directory?(srcPath) srcPathIsDirectory = File.directory?(srcPath)
if newEntry.is_directory && ! srcPathIsDirectory if newEntry.is_directory && ! srcPathIsDirectory
@ -1211,17 +1555,6 @@ module Zip
end end
end end
def write_file(entry, destPath, continueOnExistsProc = proc { false })
if File.exists?(destPath) && ! yield(entry, destPath)
raise ZipDestinationFileExistsError,
"Destination '#{destPath}' already exists"
end
File.open(destPath, "wb") {
|os|
entry.get_input_stream { |is| os << is.read }
}
end
def check_file(path) def check_file(path)
unless File.readable? path unless File.readable? path
raise Errno::ENOENT, path raise Errno::ENOENT, path
@ -1245,43 +1578,13 @@ module Zip
end end
class ZipStreamableFile < DelegateClass(ZipEntry) #:nodoc:all class ZipStreamableDirectory < ZipEntry
def initialize(entry, filepath) def initialize(zipfile, entry, srcPath = nil, permissionInt = nil)
super(entry) super(zipfile, entry)
@delegate = entry
@filepath = filepath
end
def get_input_stream(&aProc) @ftype = :directory
File.open(@filepath, "rb", &aProc) entry.get_extra_attributes_from_path(srcPath) if (srcPath)
end @unix_perms = permissionInt if (permissionInt)
def write_to_zip_output_stream(aZipOutputStream)
aZipOutputStream.put_next_entry(self)
aZipOutputStream << get_input_stream { |is| is.read }
end
def == (other)
return false unless other.class == ZipStreamableFile
@filepath == other.filepath && super(other.delegate)
end
protected
attr_reader :filepath, :delegate
end
class ZipStreamableDirectory < DelegateClass(ZipEntry) #:nodoc:all
def initialize(entry)
super(entry)
end
def get_input_stream(&aProc)
return yield(NullInputStream.instance) if block_given?
NullInputStream.instance
end
def write_to_zip_output_stream(aZipOutputStream)
aZipOutputStream.put_next_entry(self)
end end
end end
@ -1309,6 +1612,7 @@ module Zip
raise StandardError, "cannot open entry for reading while its open for writing - #{name}" raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
end end
@tempFile.open # reopens tempfile from top @tempFile.open # reopens tempfile from top
@tempFile.binmode
if block_given? if block_given?
begin begin
yield(@tempFile) yield(@tempFile)
@ -1322,7 +1626,7 @@ module Zip
def write_to_zip_output_stream(aZipOutputStream) def write_to_zip_output_stream(aZipOutputStream)
aZipOutputStream.put_next_entry(self) aZipOutputStream.put_next_entry(self)
aZipOutputStream << get_input_stream { |is| is.read } get_input_stream { |is| IOExtras.copy_stream(aZipOutputStream, is) }
end end
end end

View file

@ -482,7 +482,7 @@ module Zip
alias rmdir delete alias rmdir delete
alias unlink delete alias unlink delete
def mkdir(entryName, permissionInt = 0) def mkdir(entryName, permissionInt = 0755)
@mappedZip.mkdir(entryName, permissionInt) @mappedZip.mkdir(entryName, permissionInt)
end end
@ -571,7 +571,7 @@ module Zip
&continueOnExistsProc) &continueOnExistsProc)
end end
def mkdir(fileName, permissionInt = 0) def mkdir(fileName, permissionInt = 0755)
@zipFile.mkdir(expand_to_entry(fileName), permissionInt) @zipFile.mkdir(expand_to_entry(fileName), permissionInt)
end end

View file

View file

@ -0,0 +1,69 @@
#!/usr/bin/env ruby
$: << "../lib"
system("zip example.zip example.rb gtkRubyzip.rb")
require 'zip/zip'
####### Using ZipInputStream alone: #######
Zip::ZipInputStream.open("example.zip") {
|zis|
entry = zis.get_next_entry
print "First line of '#{entry.name} (#{entry.size} bytes): "
puts "'#{zis.gets.chomp}'"
entry = zis.get_next_entry
print "First line of '#{entry.name} (#{entry.size} bytes): "
puts "'#{zis.gets.chomp}'"
}
####### Using ZipFile to read the directory of a zip file: #######
zf = Zip::ZipFile.new("example.zip")
zf.each_with_index {
|entry, index|
puts "entry #{index} is #{entry.name}, size = #{entry.size}, compressed size = #{entry.compressed_size}"
# use zf.get_input_stream(entry) to get a ZipInputStream for the entry
# entry can be the ZipEntry object or any object which has a to_s method that
# returns the name of the entry.
}
####### Using ZipOutputStream to write a zip file: #######
Zip::ZipOutputStream.open("exampleout.zip") {
|zos|
zos.put_next_entry("the first little entry")
zos.puts "Hello hello hello hello hello hello hello hello hello"
zos.put_next_entry("the second little entry")
zos.puts "Hello again"
# Use rubyzip or your zip client of choice to verify
# the contents of exampleout.zip
}
####### Using ZipFile to change a zip file: #######
Zip::ZipFile.open("exampleout.zip") {
|zf|
zf.add("thisFile.rb", "example.rb")
zf.rename("thisFile.rb", "ILikeThisName.rb")
zf.add("Again", "example.rb")
}
# Lets check
Zip::ZipFile.open("exampleout.zip") {
|zf|
puts "Changed zip file contains: #{zf.entries.join(', ')}"
zf.remove("Again")
puts "Without 'Again': #{zf.entries.join(', ')}"
}
# For other examples, look at zip.rb and ziptest.rb
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

View file

@ -0,0 +1,34 @@
#!/usr/bin/env ruby
$: << "../lib"
require 'zip/zipfilesystem'
require 'ftools'
EXAMPLE_ZIP = "filesystem.zip"
File.delete(EXAMPLE_ZIP) if File.exists?(EXAMPLE_ZIP)
Zip::ZipFile.open(EXAMPLE_ZIP, Zip::ZipFile::CREATE) {
|zf|
zf.file.open("file1.txt", "w") { |os| os.write "first file1.txt" }
zf.dir.mkdir("dir1")
zf.dir.chdir("dir1")
zf.file.open("file1.txt", "w") { |os| os.write "second file1.txt" }
puts zf.file.read("file1.txt")
puts zf.file.read("../file1.txt")
zf.dir.chdir("..")
zf.file.open("file2.txt", "w") { |os| os.write "first file2.txt" }
puts "Entries: #{zf.entries.join(', ')}"
}
Zip::ZipFile.open(EXAMPLE_ZIP) {
|zf|
puts "Entries from reloaded zip: #{zf.entries.join(', ')}"
}
# For other examples, look at zip.rb and ziptest.rb
# Copyright (C) 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

View file

@ -0,0 +1,86 @@
#!/usr/bin/env ruby
$: << "../lib"
$VERBOSE = true
require 'gtk'
require 'zip/zip'
class MainApp < Gtk::Window
def initialize
super()
set_usize(400, 256)
set_title("rubyzip")
signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
box = Gtk::VBox.new(false, 0)
add(box)
@zipfile = nil
@buttonPanel = ButtonPanel.new
@buttonPanel.openButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
show_file_selector
}
@buttonPanel.extractButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
puts "Not implemented!"
}
box.pack_start(@buttonPanel, false, false, 0)
sw = Gtk::ScrolledWindow.new
sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
box.pack_start(sw, true, true, 0)
@clist = Gtk::CList.new(["Name", "Size", "Compression"])
@clist.set_selection_mode(Gtk::SELECTION_BROWSE)
@clist.set_column_width(0, 120)
@clist.set_column_width(1, 120)
@clist.signal_connect(Gtk::CList::SIGNAL_SELECT_ROW) {
|w, row, column, event|
@selected_row = row
}
sw.add(@clist)
end
class ButtonPanel < Gtk::HButtonBox
attr_reader :openButton, :extractButton
def initialize
super
set_layout(Gtk::BUTTONBOX_START)
set_spacing(0)
@openButton = Gtk::Button.new("Open archive")
@extractButton = Gtk::Button.new("Extract entry")
pack_start(@openButton)
pack_start(@extractButton)
end
end
def show_file_selector
@fileSelector = Gtk::FileSelection.new("Open zip file")
@fileSelector.show
@fileSelector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
open_zip(@fileSelector.filename)
@fileSelector.destroy
}
@fileSelector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
@fileSelector.destroy
}
end
def open_zip(filename)
@zipfile = Zip::ZipFile.open(filename)
@clist.clear
@zipfile.each {
|entry|
@clist.append([ entry.name,
entry.size.to_s,
(100.0*entry.compressedSize/entry.size).to_s+"%" ])
}
end
end
mainApp = MainApp.new()
mainApp.show_all
Gtk.main

101
vendor/plugins/rubyzip-0.9.1/samples/qtzip.rb vendored Executable file
View file

@ -0,0 +1,101 @@
#!/usr/bin/env ruby
$VERBOSE=true
$: << "../lib"
require 'Qt'
system('rbuic -o zipdialogui.rb zipdialogui.ui')
require 'zipdialogui.rb'
require 'zip/zip'
a = Qt::Application.new(ARGV)
class ZipDialog < ZipDialogUI
def initialize()
super()
connect(child('add_button'), SIGNAL('clicked()'),
self, SLOT('add_files()'))
connect(child('extract_button'), SIGNAL('clicked()'),
self, SLOT('extract_files()'))
end
def zipfile(&proc)
Zip::ZipFile.open(@zip_filename, &proc)
end
def each(&proc)
Zip::ZipFile.foreach(@zip_filename, &proc)
end
def refresh()
lv = child("entry_list_view")
lv.clear
each {
|e|
lv.insert_item(Qt::ListViewItem.new(lv, e.name, e.size.to_s))
}
end
def load(zipfile)
@zip_filename = zipfile
refresh
end
def add_files
l = Qt::FileDialog.getOpenFileNames(nil, nil, self)
zipfile {
|zf|
l.each {
|path|
zf.add(File.basename(path), path)
}
}
refresh
end
def extract_files
selected_items = []
unselected_items = []
lv_item = entry_list_view.first_child
while (lv_item)
if entry_list_view.is_selected(lv_item)
selected_items << lv_item.text(0)
else
unselected_items << lv_item.text(0)
end
lv_item = lv_item.next_sibling
end
puts "selected_items.size = #{selected_items.size}"
puts "unselected_items.size = #{unselected_items.size}"
items = selected_items.size > 0 ? selected_items : unselected_items
puts "items.size = #{items.size}"
d = Qt::FileDialog.get_existing_directory(nil, self)
if (!d)
puts "No directory chosen"
else
zipfile { |zf| items.each { |e| zf.extract(e, File.join(d, e)) } }
end
end
slots 'add_files()', 'extract_files()'
end
if !ARGV[0]
puts "usage: #{$0} zipname"
exit
end
zd = ZipDialog.new
zd.load(ARGV[0])
a.mainWidget = zd
zd.show()
a.exec()

View file

@ -0,0 +1,13 @@
#!/usr/bin/env ruby
$: << "../lib"
require 'zip/zip'
include Zip
ZipOutputStream.open('simple.zip') {
|zos|
ze = zos.put_next_entry 'entry.txt'
zos.puts "Hello world"
}

View file

@ -0,0 +1,74 @@
#!/usr/bin/env ruby
$VERBOSE = true
$: << "../lib"
require 'zip/zip'
require 'find'
module Zip
module ZipFind
def self.find(path, zipFilePattern = /\.zip$/i)
Find.find(path) {
|fileName|
yield(fileName)
if zipFilePattern.match(fileName) && File.file?(fileName)
begin
Zip::ZipFile.foreach(fileName) {
|zipEntry|
yield(fileName + File::SEPARATOR + zipEntry.to_s)
}
rescue Errno::EACCES => ex
puts ex
end
end
}
end
def self.find_file(path, fileNamePattern, zipFilePattern = /\.zip$/i)
self.find(path, zipFilePattern) {
|fileName|
yield(fileName) if fileNamePattern.match(fileName)
}
end
end
end
if __FILE__ == $0
module ZipFindConsoleRunner
PATH_ARG_INDEX = 0;
FILENAME_PATTERN_ARG_INDEX = 1;
ZIPFILE_PATTERN_ARG_INDEX = 2;
def self.run(args)
check_args(args)
Zip::ZipFind.find_file(args[PATH_ARG_INDEX],
args[FILENAME_PATTERN_ARG_INDEX],
args[ZIPFILE_PATTERN_ARG_INDEX]) {
|fileName|
report_entry_found fileName
}
end
def self.check_args(args)
if (args.size != 3)
usage
exit
end
end
def self.usage
puts "Usage: #{$0} PATH ZIPFILENAME_PATTERN FILNAME_PATTERN"
end
def self.report_entry_found(fileName)
puts fileName
end
end
ZipFindConsoleRunner.run(ARGV)
end

View file

@ -0,0 +1,9 @@
#!/usr/bin/env ruby
$VERBOSE = true
require 'stdrubyexttest'
require 'ioextrastest'
require 'ziptest'
require 'zipfilesystemtest'
require 'ziprequiretest'

View file

@ -0,0 +1,46 @@
AUTOMAKE_OPTIONS = gnu
EXTRA_DIST = test.zip
CXXFLAGS= -g
noinst_LIBRARIES = libzipios.a
bin_PROGRAMS = test_zip test_izipfilt test_izipstream
# test_flist
libzipios_a_SOURCES = backbuffer.h fcol.cpp fcol.h \
fcol_common.h fcolexceptions.cpp fcolexceptions.h \
fileentry.cpp fileentry.h flist.cpp \
flist.h flistentry.cpp flistentry.h \
flistscanner.h ifiltstreambuf.cpp ifiltstreambuf.h \
inflatefilt.cpp inflatefilt.h izipfilt.cpp \
izipfilt.h izipstream.cpp izipstream.h \
zipfile.cpp zipfile.h ziphead.cpp \
ziphead.h flistscanner.ll
# test_flist_SOURCES = test_flist.cpp
test_izipfilt_SOURCES = test_izipfilt.cpp
test_izipstream_SOURCES = test_izipstream.cpp
test_zip_SOURCES = test_zip.cpp
# Notice that libzipios.a is not specified as -L. -lzipios
# If it was, automake would not include it as a dependency.
# test_flist_LDADD = libzipios.a
test_izipfilt_LDADD = libzipios.a -lz
test_zip_LDADD = libzipios.a -lz
test_izipstream_LDADD = libzipios.a -lz
flistscanner.cc : flistscanner.ll
$(LEX) -+ -PFListScanner -o$@ $^

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
#!/usr/bin/env ruby
class NotZippedRuby
def returnTrue
true
end
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,157 @@
#!/usr/bin/env ruby
$VERBOSE = true
class TestFiles
RANDOM_ASCII_FILE1 = "data/generated/randomAscii1.txt"
RANDOM_ASCII_FILE2 = "data/generated/randomAscii2.txt"
RANDOM_ASCII_FILE3 = "data/generated/randomAscii3.txt"
RANDOM_BINARY_FILE1 = "data/generated/randomBinary1.bin"
RANDOM_BINARY_FILE2 = "data/generated/randomBinary2.bin"
EMPTY_TEST_DIR = "data/generated/emptytestdir"
ASCII_TEST_FILES = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ]
BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
TEST_DIRECTORIES = [ EMPTY_TEST_DIR ]
TEST_FILES = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
def TestFiles.create_test_files(recreate)
if (recreate ||
! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
Dir.mkdir "data/generated" rescue Errno::EEXIST
ASCII_TEST_FILES.each_with_index {
|filename, index|
create_random_ascii(filename, 1E4 * (index+1))
}
BINARY_TEST_FILES.each_with_index {
|filename, index|
create_random_binary(filename, 1E4 * (index+1))
}
ensure_dir(EMPTY_TEST_DIR)
end
end
private
def TestFiles.create_random_ascii(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand
end
}
end
def TestFiles.create_random_binary(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << [rand].pack("V")
end
}
end
def TestFiles.ensure_dir(name)
if File.exists?(name)
return if File.stat(name).directory?
File.delete(name)
end
Dir.mkdir(name)
end
end
# For representation and creation of
# test data
class TestZipFile
attr_accessor :zip_name, :entry_names, :comment
def initialize(zip_name, entry_names, comment = "")
@zip_name=zip_name
@entry_names=entry_names
@comment = comment
end
def TestZipFile.create_test_zips(recreate)
files = Dir.entries("data/generated")
if (recreate ||
! (files.index(File.basename(TEST_ZIP1.zip_name)) &&
files.index(File.basename(TEST_ZIP2.zip_name)) &&
files.index(File.basename(TEST_ZIP3.zip_name)) &&
files.index(File.basename(TEST_ZIP4.zip_name)) &&
files.index("empty.txt") &&
files.index("empty_chmod640.txt") &&
files.index("short.txt") &&
files.index("longAscii.txt") &&
files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} data/file2.txt")
raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} -d data/file2.txt")
File.open("data/generated/empty.txt", "w") {}
File.open("data/generated/empty_chmod640.txt", "w") { |f| f.chmod(0640) }
File.open("data/generated/short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt=""
File.open("data/file2.txt") { |file| ziptestTxt=file.read }
File.open("data/generated/longAscii.txt", "w") {
|file|
while (file.tell < 1E5)
file << ziptestTxt
end
}
testBinaryPattern=""
File.open("data/generated/empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4
File.open("data/generated/longBinary.bin", "wb") {
|file|
while (file.tell < 3E5)
file << testBinaryPattern << rand << "\0"
end
}
raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
system("zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
# without bash system interprets everything after echo as parameters to
# echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zip_name}\"")
raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless
system("zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless
system("zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
end
rescue
raise $!.to_s +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
"to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip."
end
TEST_ZIP1 = TestZipFile.new("data/generated/empty.zip", [])
TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin},
"my zip comment")
TEST_ZIP3 = TestZipFile.new("data/generated/test1.zip", %w{ data/file1.txt })
TEST_ZIP4 = TestZipFile.new("data/generated/zipWithDir.zip", [ "data/file1.txt",
TestFiles::EMPTY_TEST_DIR])
end
END {
TestFiles::create_test_files(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
TestZipFile::create_test_zips(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
exit if ARGV.index("recreateonly") != nil
}

View file

@ -0,0 +1,208 @@
#!/usr/bin/env ruby
$VERBOSE = true
$: << "../lib"
require 'test/unit'
require 'zip/ioextras'
include IOExtras
class FakeIOTest < Test::Unit::TestCase
class FakeIOUsingClass
include FakeIO
end
def test_kind_of?
obj = FakeIOUsingClass.new
assert(obj.kind_of?(Object))
assert(obj.kind_of?(FakeIOUsingClass))
assert(obj.kind_of?(IO))
assert(!obj.kind_of?(Fixnum))
assert(!obj.kind_of?(String))
end
end
class AbstractInputStreamTest < Test::Unit::TestCase
# AbstractInputStream subclass that provides a read method
TEST_LINES = [ "Hello world#{$/}",
"this is the second line#{$/}",
"this is the last line"]
TEST_STRING = TEST_LINES.join
class TestAbstractInputStream
include AbstractInputStream
def initialize(aString)
super()
@contents = aString
@readPointer = 0
end
def read(charsToRead)
retVal=@contents[@readPointer, charsToRead]
@readPointer+=charsToRead
return retVal
end
def produce_input
read(100)
end
def input_finished?
@contents[@readPointer] == nil
end
end
def setup
@io = TestAbstractInputStream.new(TEST_STRING)
end
def test_gets
assert_equal(TEST_LINES[0], @io.gets)
assert_equal(1, @io.lineno)
assert_equal(TEST_LINES[1], @io.gets)
assert_equal(2, @io.lineno)
assert_equal(TEST_LINES[2], @io.gets)
assert_equal(3, @io.lineno)
assert_equal(nil, @io.gets)
assert_equal(4, @io.lineno)
end
def test_getsMultiCharSeperator
assert_equal("Hell", @io.gets("ll"))
assert_equal("o world#{$/}this is the second l", @io.gets("d l"))
end
def test_each_line
lineNumber=0
@io.each_line {
|line|
assert_equal(TEST_LINES[lineNumber], line)
lineNumber+=1
}
end
def test_readlines
assert_equal(TEST_LINES, @io.readlines)
end
def test_readline
test_gets
begin
@io.readline
fail "EOFError expected"
rescue EOFError
end
end
end
class AbstractOutputStreamTest < Test::Unit::TestCase
class TestOutputStream
include AbstractOutputStream
attr_accessor :buffer
def initialize
@buffer = ""
end
def << (data)
@buffer << data
self
end
end
def setup
@outputStream = TestOutputStream.new
@origCommaSep = $,
@origOutputSep = $\
end
def teardown
$, = @origCommaSep
$\ = @origOutputSep
end
def test_write
count = @outputStream.write("a little string")
assert_equal("a little string", @outputStream.buffer)
assert_equal("a little string".length, count)
count = @outputStream.write(". a little more")
assert_equal("a little string. a little more", @outputStream.buffer)
assert_equal(". a little more".length, count)
end
def test_print
$\ = nil # record separator set to nil
@outputStream.print("hello")
assert_equal("hello", @outputStream.buffer)
@outputStream.print(" world.")
assert_equal("hello world.", @outputStream.buffer)
@outputStream.print(" You ok ", "out ", "there?")
assert_equal("hello world. You ok out there?", @outputStream.buffer)
$\ = "\n"
@outputStream.print
assert_equal("hello world. You ok out there?\n", @outputStream.buffer)
@outputStream.print("I sure hope so!")
assert_equal("hello world. You ok out there?\nI sure hope so!\n", @outputStream.buffer)
$, = "X"
@outputStream.buffer = ""
@outputStream.print("monkey", "duck", "zebra")
assert_equal("monkeyXduckXzebra\n", @outputStream.buffer)
$\ = nil
@outputStream.buffer = ""
@outputStream.print(20)
assert_equal("20", @outputStream.buffer)
end
def test_printf
@outputStream.printf("%d %04x", 123, 123)
assert_equal("123 007b", @outputStream.buffer)
end
def test_putc
@outputStream.putc("A")
assert_equal("A", @outputStream.buffer)
@outputStream.putc(65)
assert_equal("AA", @outputStream.buffer)
end
def test_puts
@outputStream.puts
assert_equal("\n", @outputStream.buffer)
@outputStream.puts("hello", "world")
assert_equal("\nhello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts("hello\n", "world\n")
assert_equal("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"])
assert_equal("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"], "bingo")
assert_equal("hello\nworld\nbingo\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(16, 20, 50, "hello")
assert_equal("16\n20\n50\nhello\n", @outputStream.buffer)
end
end
# Copyright (C) 2002-2004 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

View file

@ -0,0 +1,52 @@
#!/usr/bin/env ruby
$VERBOSE = true
$: << "../lib"
require 'test/unit'
require 'zip/stdrubyext'
class ModuleTest < Test::Unit::TestCase
def test_select_map
assert_equal([2, 4, 8, 10], [1, 2, 3, 4, 5].select_map { |e| e == 3 ? nil : 2*e })
end
end
class StringExtensionsTest < Test::Unit::TestCase
def test_starts_with
assert("hello".starts_with(""))
assert("hello".starts_with("h"))
assert("hello".starts_with("he"))
assert(! "hello".starts_with("hello there"))
assert(! "hello".starts_with(" he"))
assert_raise(TypeError, "type mismatch: NilClass given") {
"hello".starts_with(nil)
}
end
def test_ends_with
assert("hello".ends_with("o"))
assert("hello".ends_with("lo"))
assert("hello".ends_with("hello"))
assert(!"howdy".ends_with("o"))
assert(!"howdy".ends_with("oy"))
assert(!"howdy".ends_with("howdy doody"))
assert(!"howdy".ends_with("doody howdy"))
end
def test_ensure_end
assert_equal("hello!", "hello!".ensure_end("!"))
assert_equal("hello!", "hello!".ensure_end("o!"))
assert_equal("hello!", "hello".ensure_end("!"))
assert_equal("hello!", "hel".ensure_end("lo!"))
end
end
# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

View file

@ -0,0 +1,831 @@
#!/usr/bin/env ruby
$VERBOSE = true
$: << "../lib"
require 'zip/zipfilesystem'
require 'test/unit'
module ExtraAssertions
def assert_forwarded(anObject, method, retVal, *expectedArgs)
callArgs = nil
setCallArgsProc = proc { |args| callArgs = args }
anObject.instance_eval <<-"end_eval"
alias #{method}_org #{method}
def #{method}(*args)
ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args)
ObjectSpace._id2ref(#{retVal.object_id})
end
end_eval
assert_equal(retVal, yield) # Invoke test
assert_equal(expectedArgs, callArgs)
ensure
anObject.instance_eval "alias #{method} #{method}_org"
end
end
include Zip
class ZipFsFileNonmutatingTest < Test::Unit::TestCase
def setup
@zipFile = ZipFile.new("data/zipWithDirs.zip")
end
def teardown
@zipFile.close if @zipFile
end
def test_umask
assert_equal(File.umask, @zipFile.file.umask)
@zipFile.file.umask(0006)
end
def test_exists?
assert(! @zipFile.file.exists?("notAFile"))
assert(@zipFile.file.exists?("file1"))
assert(@zipFile.file.exists?("dir1"))
assert(@zipFile.file.exists?("dir1/"))
assert(@zipFile.file.exists?("dir1/file12"))
assert(@zipFile.file.exist?("dir1/file12")) # notice, tests exist? alias of exists? !
@zipFile.dir.chdir "dir1/"
assert(!@zipFile.file.exists?("file1"))
assert(@zipFile.file.exists?("file12"))
end
def test_open_read
blockCalled = false
@zipFile.file.open("file1", "r") {
|f|
blockCalled = true
assert_equal("this is the entry 'file1' in my test archive!",
f.readline.chomp)
}
assert(blockCalled)
blockCalled = false
@zipFile.dir.chdir "dir2"
@zipFile.file.open("file21", "r") {
|f|
blockCalled = true
assert_equal("this is the entry 'dir2/file21' in my test archive!",
f.readline.chomp)
}
assert(blockCalled)
@zipFile.dir.chdir "/"
assert_raise(Errno::ENOENT) {
@zipFile.file.open("noSuchEntry")
}
begin
is = @zipFile.file.open("file1")
assert_equal("this is the entry 'file1' in my test archive!",
is.readline.chomp)
ensure
is.close if is
end
end
def test_new
begin
is = @zipFile.file.new("file1")
assert_equal("this is the entry 'file1' in my test archive!",
is.readline.chomp)
ensure
is.close if is
end
begin
is = @zipFile.file.new("file1") {
fail "should not call block"
}
ensure
is.close if is
end
end
def test_symlink
assert_raise(NotImplementedError) {
@zipFile.file.symlink("file1", "aSymlink")
}
end
def test_size
assert_raise(Errno::ENOENT) { @zipFile.file.size("notAFile") }
assert_equal(72, @zipFile.file.size("file1"))
assert_equal(0, @zipFile.file.size("dir2/dir21"))
assert_equal(72, @zipFile.file.stat("file1").size)
assert_equal(0, @zipFile.file.stat("dir2/dir21").size)
end
def test_size?
assert_equal(nil, @zipFile.file.size?("notAFile"))
assert_equal(72, @zipFile.file.size?("file1"))
assert_equal(nil, @zipFile.file.size?("dir2/dir21"))
assert_equal(72, @zipFile.file.stat("file1").size?)
assert_equal(nil, @zipFile.file.stat("dir2/dir21").size?)
end
def test_file?
assert(@zipFile.file.file?("file1"))
assert(@zipFile.file.file?("dir2/file21"))
assert(! @zipFile.file.file?("dir1"))
assert(! @zipFile.file.file?("dir1/dir11"))
assert(@zipFile.file.stat("file1").file?)
assert(@zipFile.file.stat("dir2/file21").file?)
assert(! @zipFile.file.stat("dir1").file?)
assert(! @zipFile.file.stat("dir1/dir11").file?)
end
include ExtraAssertions
def test_dirname
assert_forwarded(File, :dirname, "retVal", "a/b/c/d") {
@zipFile.file.dirname("a/b/c/d")
}
end
def test_basename
assert_forwarded(File, :basename, "retVal", "a/b/c/d") {
@zipFile.file.basename("a/b/c/d")
}
end
def test_split
assert_forwarded(File, :split, "retVal", "a/b/c/d") {
@zipFile.file.split("a/b/c/d")
}
end
def test_join
assert_equal("a/b/c", @zipFile.file.join("a/b", "c"))
assert_equal("a/b/c/d", @zipFile.file.join("a/b", "c/d"))
assert_equal("/c/d", @zipFile.file.join("", "c/d"))
assert_equal("a/b/c/d", @zipFile.file.join("a", "b", "c", "d"))
end
def test_utime
t_now = Time.now
t_bak = @zipFile.file.mtime("file1")
@zipFile.file.utime(t_now, "file1")
assert_equal(t_now, @zipFile.file.mtime("file1"))
@zipFile.file.utime(t_bak, "file1")
assert_equal(t_bak, @zipFile.file.mtime("file1"))
end
def assert_always_false(operation)
assert(! @zipFile.file.send(operation, "noSuchFile"))
assert(! @zipFile.file.send(operation, "file1"))
assert(! @zipFile.file.send(operation, "dir1"))
assert(! @zipFile.file.stat("file1").send(operation))
assert(! @zipFile.file.stat("dir1").send(operation))
end
def assert_true_if_entry_exists(operation)
assert(! @zipFile.file.send(operation, "noSuchFile"))
assert(@zipFile.file.send(operation, "file1"))
assert(@zipFile.file.send(operation, "dir1"))
assert(@zipFile.file.stat("file1").send(operation))
assert(@zipFile.file.stat("dir1").send(operation))
end
def test_pipe?
assert_always_false(:pipe?)
end
def test_blockdev?
assert_always_false(:blockdev?)
end
def test_symlink?
assert_always_false(:symlink?)
end
def test_socket?
assert_always_false(:socket?)
end
def test_chardev?
assert_always_false(:chardev?)
end
def test_truncate
assert_raise(StandardError, "truncate not supported") {
@zipFile.file.truncate("file1", 100)
}
end
def assert_e_n_o_e_n_t(operation, args = ["NoSuchFile"])
assert_raise(Errno::ENOENT) {
@zipFile.file.send(operation, *args)
}
end
def test_ftype
assert_e_n_o_e_n_t(:ftype)
assert_equal("file", @zipFile.file.ftype("file1"))
assert_equal("directory", @zipFile.file.ftype("dir1/dir11"))
assert_equal("directory", @zipFile.file.ftype("dir1/dir11/"))
end
def test_link
assert_raise(NotImplementedError) {
@zipFile.file.link("file1", "someOtherString")
}
end
def test_directory?
assert(! @zipFile.file.directory?("notAFile"))
assert(! @zipFile.file.directory?("file1"))
assert(! @zipFile.file.directory?("dir1/file11"))
assert(@zipFile.file.directory?("dir1"))
assert(@zipFile.file.directory?("dir1/"))
assert(@zipFile.file.directory?("dir2/dir21"))
assert(! @zipFile.file.stat("file1").directory?)
assert(! @zipFile.file.stat("dir1/file11").directory?)
assert(@zipFile.file.stat("dir1").directory?)
assert(@zipFile.file.stat("dir1/").directory?)
assert(@zipFile.file.stat("dir2/dir21").directory?)
end
def test_chown
assert_equal(2, @zipFile.file.chown(1,2, "dir1", "file1"))
assert_equal(1, @zipFile.file.stat("dir1").uid)
assert_equal(2, @zipFile.file.stat("dir1").gid)
assert_equal(2, @zipFile.file.chown(nil, nil, "dir1", "file1"))
end
def test_zero?
assert(! @zipFile.file.zero?("notAFile"))
assert(! @zipFile.file.zero?("file1"))
assert(@zipFile.file.zero?("dir1"))
blockCalled = false
ZipFile.open("data/generated/5entry.zip") {
|zf|
blockCalled = true
assert(zf.file.zero?("data/generated/empty.txt"))
}
assert(blockCalled)
assert(! @zipFile.file.stat("file1").zero?)
assert(@zipFile.file.stat("dir1").zero?)
blockCalled = false
ZipFile.open("data/generated/5entry.zip") {
|zf|
blockCalled = true
assert(zf.file.stat("data/generated/empty.txt").zero?)
}
assert(blockCalled)
end
def test_expand_path
ZipFile.open("data/zipWithDirs.zip") {
|zf|
assert_equal("/", zf.file.expand_path("."))
zf.dir.chdir "dir1"
assert_equal("/dir1", zf.file.expand_path("."))
assert_equal("/dir1/file12", zf.file.expand_path("file12"))
assert_equal("/", zf.file.expand_path(".."))
assert_equal("/dir2/dir21", zf.file.expand_path("../dir2/dir21"))
}
end
def test_mtime
assert_equal(Time.at(1027694306),
@zipFile.file.mtime("dir2/file21"))
assert_equal(Time.at(1027690863),
@zipFile.file.mtime("dir2/dir21"))
assert_raise(Errno::ENOENT) {
@zipFile.file.mtime("noSuchEntry")
}
assert_equal(Time.at(1027694306),
@zipFile.file.stat("dir2/file21").mtime)
assert_equal(Time.at(1027690863),
@zipFile.file.stat("dir2/dir21").mtime)
end
def test_ctime
assert_nil(@zipFile.file.ctime("file1"))
assert_nil(@zipFile.file.stat("file1").ctime)
end
def test_atime
assert_nil(@zipFile.file.atime("file1"))
assert_nil(@zipFile.file.stat("file1").atime)
end
def test_readable?
assert(! @zipFile.file.readable?("noSuchFile"))
assert(@zipFile.file.readable?("file1"))
assert(@zipFile.file.readable?("dir1"))
assert(@zipFile.file.stat("file1").readable?)
assert(@zipFile.file.stat("dir1").readable?)
end
def test_readable_real?
assert(! @zipFile.file.readable_real?("noSuchFile"))
assert(@zipFile.file.readable_real?("file1"))
assert(@zipFile.file.readable_real?("dir1"))
assert(@zipFile.file.stat("file1").readable_real?)
assert(@zipFile.file.stat("dir1").readable_real?)
end
def test_writable?
assert(! @zipFile.file.writable?("noSuchFile"))
assert(@zipFile.file.writable?("file1"))
assert(@zipFile.file.writable?("dir1"))
assert(@zipFile.file.stat("file1").writable?)
assert(@zipFile.file.stat("dir1").writable?)
end
def test_writable_real?
assert(! @zipFile.file.writable_real?("noSuchFile"))
assert(@zipFile.file.writable_real?("file1"))
assert(@zipFile.file.writable_real?("dir1"))
assert(@zipFile.file.stat("file1").writable_real?)
assert(@zipFile.file.stat("dir1").writable_real?)
end
def test_executable?
assert(! @zipFile.file.executable?("noSuchFile"))
assert(! @zipFile.file.executable?("file1"))
assert(@zipFile.file.executable?("dir1"))
assert(! @zipFile.file.stat("file1").executable?)
assert(@zipFile.file.stat("dir1").executable?)
end
def test_executable_real?
assert(! @zipFile.file.executable_real?("noSuchFile"))
assert(! @zipFile.file.executable_real?("file1"))
assert(@zipFile.file.executable_real?("dir1"))
assert(! @zipFile.file.stat("file1").executable_real?)
assert(@zipFile.file.stat("dir1").executable_real?)
end
def test_owned?
assert_true_if_entry_exists(:owned?)
end
def test_grpowned?
assert_true_if_entry_exists(:grpowned?)
end
def test_setgid?
assert_always_false(:setgid?)
end
def test_setuid?
assert_always_false(:setgid?)
end
def test_sticky?
assert_always_false(:sticky?)
end
def test_readlink
assert_raise(NotImplementedError) {
@zipFile.file.readlink("someString")
}
end
def test_stat
s = @zipFile.file.stat("file1")
assert(s.kind_of?(File::Stat)) # It pretends
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
@zipFile.file.stat("noSuchFile")
}
end
def test_lstat
assert(@zipFile.file.lstat("file1").file?)
end
def test_chmod
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
@zipFile.file.chmod(0644, "file1", "NoSuchFile")
}
assert_equal(2, @zipFile.file.chmod(0644, "file1", "dir1"))
end
def test_pipe
assert_raise(NotImplementedError) {
@zipFile.file.pipe
}
end
def test_foreach
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
ref = []
File.foreach("data/file1.txt") { |e| ref << e }
index = 0
zf.file.foreach("data/file1.txt") {
|l|
assert_equal(ref[index], l)
index = index.next
}
assert_equal(ref.size, index)
}
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
ref = []
File.foreach("data/file1.txt", " ") { |e| ref << e }
index = 0
zf.file.foreach("data/file1.txt", " ") {
|l|
assert_equal(ref[index], l)
index = index.next
}
assert_equal(ref.size, index)
}
end
def test_popen
cmd = /mswin/i =~ RUBY_PLATFORM ? 'dir' : 'ls'
assert_equal(File.popen(cmd) { |f| f.read },
@zipFile.file.popen(cmd) { |f| f.read })
end
# Can be added later
# def test_select
# fail "implement test"
# end
def test_readlines
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
assert_equal(File.readlines("data/file1.txt"),
zf.file.readlines("data/file1.txt"))
}
end
def test_read
ZipFile.open("data/generated/zipWithDir.zip") {
|zf|
assert_equal(File.read("data/file1.txt"),
zf.file.read("data/file1.txt"))
}
end
end
class ZipFsFileStatTest < Test::Unit::TestCase
def setup
@zipFile = ZipFile.new("data/zipWithDirs.zip")
end
def teardown
@zipFile.close if @zipFile
end
def test_blocks
assert_equal(nil, @zipFile.file.stat("file1").blocks)
end
def test_ino
assert_equal(0, @zipFile.file.stat("file1").ino)
end
def test_uid
assert_equal(0, @zipFile.file.stat("file1").uid)
end
def test_gid
assert_equal(0, @zipFile.file.stat("file1").gid)
end
def test_ftype
assert_equal("file", @zipFile.file.stat("file1").ftype)
assert_equal("directory", @zipFile.file.stat("dir1").ftype)
end
def test_mode
assert_equal(0600, @zipFile.file.stat("file1").mode & 0777)
assert_equal(0600, @zipFile.file.stat("file1").mode & 0777)
assert_equal(0755, @zipFile.file.stat("dir1").mode & 0777)
assert_equal(0755, @zipFile.file.stat("dir1").mode & 0777)
end
def test_dev
assert_equal(0, @zipFile.file.stat("file1").dev)
end
def test_rdev
assert_equal(0, @zipFile.file.stat("file1").rdev)
end
def test_rdev_major
assert_equal(0, @zipFile.file.stat("file1").rdev_major)
end
def test_rdev_minor
assert_equal(0, @zipFile.file.stat("file1").rdev_minor)
end
def test_nlink
assert_equal(1, @zipFile.file.stat("file1").nlink)
end
def test_blksize
assert_nil(@zipFile.file.stat("file1").blksize)
end
end
class ZipFsFileMutatingTest < Test::Unit::TestCase
TEST_ZIP = "zipWithDirs_copy.zip"
def setup
File.copy("data/zipWithDirs.zip", TEST_ZIP)
end
def teardown
end
def test_delete
do_test_delete_or_unlink(:delete)
end
def test_unlink
do_test_delete_or_unlink(:unlink)
end
def test_open_write
ZipFile.open(TEST_ZIP) {
|zf|
zf.file.open("test_open_write_entry", "w") {
|f|
blockCalled = true
f.write "This is what I'm writing"
}
assert_equal("This is what I'm writing",
zf.file.read("test_open_write_entry"))
# Test with existing entry
zf.file.open("file1", "w") {
|f|
blockCalled = true
f.write "This is what I'm writing too"
}
assert_equal("This is what I'm writing too",
zf.file.read("file1"))
}
end
def test_rename
ZipFile.open(TEST_ZIP) {
|zf|
assert_raise(Errno::ENOENT, "") {
zf.file.rename("NoSuchFile", "bimse")
}
zf.file.rename("file1", "newNameForFile1")
}
ZipFile.open(TEST_ZIP) {
|zf|
assert(! zf.file.exists?("file1"))
assert(zf.file.exists?("newNameForFile1"))
}
end
def do_test_delete_or_unlink(symbol)
ZipFile.open(TEST_ZIP) {
|zf|
assert(zf.file.exists?("dir2/dir21/dir221/file2221"))
zf.file.send(symbol, "dir2/dir21/dir221/file2221")
assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
assert(zf.file.exists?("dir1/file11"))
assert(zf.file.exists?("dir1/file12"))
zf.file.send(symbol, "dir1/file11", "dir1/file12")
assert(! zf.file.exists?("dir1/file11"))
assert(! zf.file.exists?("dir1/file12"))
assert_raise(Errno::ENOENT) { zf.file.send(symbol, "noSuchFile") }
assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11") }
assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11/") }
}
ZipFile.open(TEST_ZIP) {
|zf|
assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
assert(! zf.file.exists?("dir1/file11"))
assert(! zf.file.exists?("dir1/file12"))
assert(zf.file.exists?("dir1/dir11"))
assert(zf.file.exists?("dir1/dir11/"))
}
end
end
class ZipFsDirectoryTest < Test::Unit::TestCase
TEST_ZIP = "zipWithDirs_copy.zip"
def setup
File.copy("data/zipWithDirs.zip", TEST_ZIP)
end
def test_delete
ZipFile.open(TEST_ZIP) {
|zf|
assert_raise(Errno::ENOENT, "No such file or directory - NoSuchFile.txt") {
zf.dir.delete("NoSuchFile.txt")
}
assert_raise(Errno::EINVAL, "Invalid argument - file1") {
zf.dir.delete("file1")
}
assert(zf.file.exists?("dir1"))
zf.dir.delete("dir1")
assert(! zf.file.exists?("dir1"))
}
end
def test_mkdir
ZipFile.open(TEST_ZIP) {
|zf|
assert_raise(Errno::EEXIST, "File exists - dir1") {
zf.dir.mkdir("file1")
}
assert_raise(Errno::EEXIST, "File exists - dir1") {
zf.dir.mkdir("dir1")
}
assert(!zf.file.exists?("newDir"))
zf.dir.mkdir("newDir")
assert(zf.file.directory?("newDir"))
assert(!zf.file.exists?("newDir2"))
zf.dir.mkdir("newDir2", 3485)
assert(zf.file.directory?("newDir2"))
}
end
def test_pwd_chdir_entries
ZipFile.open(TEST_ZIP) {
|zf|
assert_equal("/", zf.dir.pwd)
assert_raise(Errno::ENOENT, "No such file or directory - no such dir") {
zf.dir.chdir "no such dir"
}
assert_raise(Errno::EINVAL, "Invalid argument - file1") {
zf.dir.chdir "file1"
}
assert_equal(["dir1", "dir2", "file1"].sort, zf.dir.entries(".").sort)
zf.dir.chdir "dir1"
assert_equal("/dir1", zf.dir.pwd)
assert_equal(["dir11", "file11", "file12"], zf.dir.entries(".").sort)
zf.dir.chdir "../dir2/dir21"
assert_equal("/dir2/dir21", zf.dir.pwd)
assert_equal(["dir221"].sort, zf.dir.entries(".").sort)
}
end
def test_foreach
ZipFile.open(TEST_ZIP) {
|zf|
blockCalled = false
assert_raise(Errno::ENOENT, "No such file or directory - noSuchDir") {
zf.dir.foreach("noSuchDir") { |e| blockCalled = true }
}
assert(! blockCalled)
assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
zf.dir.foreach("file1") { |e| blockCalled = true }
}
assert(! blockCalled)
entries = []
zf.dir.foreach(".") { |e| entries << e }
assert_equal(["dir1", "dir2", "file1"].sort, entries.sort)
entries = []
zf.dir.foreach("dir1") { |e| entries << e }
assert_equal(["dir11", "file11", "file12"], entries.sort)
}
end
def test_chroot
ZipFile.open(TEST_ZIP) {
|zf|
assert_raise(NotImplementedError) {
zf.dir.chroot
}
}
end
# Globbing not supported yet
#def test_glob
# # test alias []-operator too
# fail "implement test"
#end
def test_open_new
ZipFile.open(TEST_ZIP) {
|zf|
assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
zf.dir.new("file1")
}
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
zf.dir.new("noSuchFile")
}
d = zf.dir.new(".")
assert_equal(["file1", "dir1", "dir2"].sort, d.entries.sort)
d.close
zf.dir.open("dir1") {
|d|
assert_equal(["dir11", "file11", "file12"].sort, d.entries.sort)
}
}
end
end
class ZipFsDirIteratorTest < Test::Unit::TestCase
FILENAME_ARRAY = [ "f1", "f2", "f3", "f4", "f5", "f6" ]
def setup
@dirIt = ZipFileSystem::ZipFsDirIterator.new(FILENAME_ARRAY)
end
def test_close
@dirIt.close
assert_raise(IOError, "closed directory") {
@dirIt.each { |e| p e }
}
assert_raise(IOError, "closed directory") {
@dirIt.read
}
assert_raise(IOError, "closed directory") {
@dirIt.rewind
}
assert_raise(IOError, "closed directory") {
@dirIt.seek(0)
}
assert_raise(IOError, "closed directory") {
@dirIt.tell
}
end
def test_each
# Tested through Enumerable.entries
assert_equal(FILENAME_ARRAY, @dirIt.entries)
end
def test_read
FILENAME_ARRAY.size.times {
|i|
assert_equal(FILENAME_ARRAY[i], @dirIt.read)
}
end
def test_rewind
@dirIt.read
@dirIt.read
assert_equal(FILENAME_ARRAY[2], @dirIt.read)
@dirIt.rewind
assert_equal(FILENAME_ARRAY[0], @dirIt.read)
end
def test_tell_seek
@dirIt.read
@dirIt.read
pos = @dirIt.tell
valAtPos = @dirIt.read
@dirIt.read
@dirIt.seek(pos)
assert_equal(valAtPos, @dirIt.read)
end
end
# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

View file

@ -0,0 +1,43 @@
#!/usr/bin/env ruby
$VERBOSE = true
$: << "../lib"
require 'test/unit'
require 'zip/ziprequire'
$: << 'data/rubycode.zip' << 'data/rubycode2.zip'
class ZipRequireTest < Test::Unit::TestCase
def test_require
assert(require('data/notzippedruby'))
assert(!require('data/notzippedruby'))
assert(require('zippedruby1'))
assert(!require('zippedruby1'))
assert(require('zippedruby2'))
assert(!require('zippedruby2'))
assert(require('zippedruby3'))
assert(!require('zippedruby3'))
c1 = NotZippedRuby.new
assert(c1.returnTrue)
assert(ZippedRuby1.returnTrue)
assert(!ZippedRuby2.returnFalse)
assert_equal(4, ZippedRuby3.multiplyValues(2, 2))
end
def test_get_resource
get_resource("aResource.txt") {
|f|
assert_equal("Nothing exciting in this file!", f.read)
}
end
end
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.

1599
vendor/plugins/rubyzip-0.9.1/test/ziptest.rb vendored Executable file

File diff suppressed because it is too large Load diff