Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

RubyZip 0.9.1, released 2006-07-01

  • Loading branch information...
commit ddeb10baf758714621e69f3795bf939680ffa771 0 parents
@nbibler authored
Showing with 9,285 additions and 0 deletions.
  1. +1,081 −0 ChangeLog
  2. +144 −0 NEWS
  3. +72 −0 README
  4. +110 −0 Rakefile
  5. +16 −0 TODO
  6. +22 −0 install.rb
  7. +155 −0 lib/zip/ioextras.rb
  8. +111 −0 lib/zip/stdrubyext.rb
  9. +195 −0 lib/zip/tempfile_bugfixed.rb
  10. +1,847 −0 lib/zip/zip.rb
  11. +609 −0 lib/zip/zipfilesystem.rb
  12. +90 −0 lib/zip/ziprequire.rb
  13. +69 −0 samples/example.rb
  14. +34 −0 samples/example_filesystem.rb
  15. +86 −0 samples/gtkRubyzip.rb
  16. +101 −0 samples/qtzip.rb
  17. +13 −0 samples/write_simple.rb
  18. +74 −0 samples/zipfind.rb
  19. +9 −0 test/alltests.rb
  20. +46 −0 test/data/file1.txt
  21. BIN  test/data/file1.txt.deflatedData
  22. +1,504 −0 test/data/file2.txt
  23. +7 −0 test/data/notzippedruby.rb
  24. BIN  test/data/rubycode.zip
  25. BIN  test/data/rubycode2.zip
  26. BIN  test/data/testDirectory.bin
  27. BIN  test/data/zipWithDirs.zip
  28. +157 −0 test/gentestfiles.rb
  29. +208 −0 test/ioextrastest.rb
  30. +52 −0 test/stdrubyexttest.rb
  31. +831 −0 test/zipfilesystemtest.rb
  32. +43 −0 test/ziprequiretest.rb
  33. +1,599 −0 test/ziptest.rb
1,081 ChangeLog
@@ -0,0 +1,1081 @@
+2006-07-01 10:04 thomas
+
+ * Rakefile: Don't autorequire zip/zip - autorequire is deprecated.
+
+2006-06-30 09:28 thomas
+
+ * Rakefile: [no log message]
+
+ * NEWS, lib/zip/zip.rb: Bumped version number and reformatted NEWS
+ a bit.
+
+2006-06-29 22:49 technorama
+
+ * lib/zip/zip.rb, NEWS: documentation additions
+
+2006-04-30 06:25 technorama
+
+ * TODO, lib/zip/zip.rb, test/ziptest.rb: add documentation and test
+ for new ZipFile::extract
+
+ * lib/zip/zip.rb: add some of the API suggestions from sf.net
+ #1281314
+
+ * lib/zip/zip.rb: apply patch for bug #1446926
+
+ * lib/zip/zip.rb: apply patch for bug #1459902
+
+2006-04-26 17:17 technorama
+
+ * lib/zip/zip.rb: add ZipFile @restore_*, documentation update
+
+2006-04-07 21:13 technorama
+
+ * test/: gentestfiles.rb, zipfilesystemtest.rb, ziptest.rb:
+ additional tests
+
+2006-03-28 04:11 technorama
+
+ * lib/zip/zip.rb: start of unix_uid, unix_gid, restore_* support
+
+ * lib/zip/zip.rb: follow_symlinks is now optional
+
+ * lib/zip/zip.rb: add eof? methods
+
+ * test/ziptest.rb: eof? tests
+
+2006-02-26 09:57 technorama
+
+ * README: add to authors
+
+ * TODO: [no log message]
+
+2006-02-25 12:04 thomas
+
+ * lib/zip/zip.rb, test/ziptest.rb: Did away with ZipStreamableFile.
+
+2006-02-23 08:03 technorama
+
+ * lib/zip/zip.rb: unix file permissions. symlink support. rework
+ ZipEntry and delegate classes. reduce memory usage during
+ decompression.
+
+2006-02-22 23:44 technorama
+
+ * lib/zip/zipfilesystem.rb: update permissionInt for mkdir
+
+2006-02-04 10:42 thomas
+
+ * lib/zip/: ioextras.rb, zip.rb: Merged patch from oss-ruby.
+
+2005-11-19 16:17 thomas
+
+ * lib/zip/zip.rb: [no log message]
+
+2005-11-08 08:23 thomas
+
+ * lib/zip/ioextras.rb: Accepted patch from oss-ruby
+
+2005-10-07 09:54 thomas
+
+ * TODO: [no log message]
+
+2005-09-06 21:19 thomas
+
+ * lib/zip/zip.rb: [no log message]
+
+ * NEWS: [no log message]
+
+ * lib/zip/zip.rb, test/gentestfiles.rb, test/ziptest.rb: Fixed
+ problem on windows - tempfile has to be set to binmode again when
+ it is reopened
+
+2005-09-04 16:45 thomas
+
+ * Rakefile: [no log message]
+
+ * TODO: [no log message]
+
+ * test/ziptest.rb: [no log message]
+
+2005-09-03 10:27 thomas
+
+ * NEWS: [no log message]
+
+ * TODO, lib/zip/zip.rb: [no log message]
+
+ * lib/zip/ioextras.rb, lib/zip/zip.rb, test/ziptest.rb: Merged
+ patch from oss-ruby at technorama.net
+
+ * test/ziptest.rb: Added failing test that shows that read and gets
+ don't mix currently
+
+2005-08-29 08:50 thomas
+
+ * lib/zip/: ioextras.rb, zip.rb: [no log message]
+
+ * NEWS, lib/zip/zip.rb: [no log message]
+
+ * lib/zip/zip.rb: [no log message]
+
+ * lib/zip/zip.rb: [no log message]
+
+2005-08-07 14:27 thomas
+
+ * lib/zip/zip.rb, NEWS: [no log message]
+
+2005-08-06 11:12 thomas
+
+ * lib/zip/: ioextras.rb, zip.rb: [no log message]
+
+2005-08-03 18:54 thomas
+
+ * lib/zip/zip.rb: Read/write in chunks to preserve memory
+
+2005-07-02 15:08 thomas
+
+ * lib/zip/zip.rb: Applied received patch concerning FreeBSD 4.5
+ issue
+
+2005-04-03 16:52 thomas
+
+ * samples/.cvsignore: [no log message]
+
+ * samples/: qtzip.rb, zipdialogui.ui: Added a qt example
+
+2005-03-31 21:58 thomas
+
+ * lib/zip/zip.rb, test/ziptest.rb: [no log message]
+
+ * test/zipfilesystemtest.rb: [no log message]
+
+2005-03-17 18:17 thomas
+
+ * Rakefile: [no log message]
+
+ * NEWS, README, lib/zip/zip.rb: [no log message]
+
+ * install.rb: Fixed install.rb
+
+2005-03-03 18:38 thomas
+
+ * Rakefile: [no log message]
+
+2005-02-27 16:23 thomas
+
+ * lib/zip/ziprequire.rb: Added documentation to ziprequire
+
+ * README, TODO, lib/zip/ziprequire.rb: Added documentation to
+ ziprequire
+
+ * Rakefile, test/ziptest.rb: [no log message]
+
+2005-02-19 21:30 thomas
+
+ * lib/zip/ioextras.rb, lib/zip/stdrubyext.rb,
+ lib/zip/tempfile_bugfixed.rb, lib/zip/zip.rb,
+ lib/zip/ziprequire.rb, test/ioextrastest.rb,
+ test/stdrubyexttest.rb, test/zipfilesystemtest.rb,
+ test/ziprequiretest.rb, test/ziptest.rb: Added more rdoc and
+ changed the remaining tests to Test::Unit
+
+ * lib/zip/: ioextras.rb, zip.rb: Added documentation to
+ ZipInputStream and ZipOutputStream
+
+2005-02-18 10:27 thomas
+
+ * README: [no log message]
+
+2005-02-17 23:21 thomas
+
+ * README, Rakefile: Added ppackage (publish package) task to
+ Rakefile
+
+ * README, Rakefile, TODO: Added pdoc (publish doc) task to Rakefile
+
+ * README, Rakefile, TODO, lib/zip/stdrubyext.rb, lib/zip/zip.rb,
+ lib/zip/zipfilesystem.rb: Added a bunch of documentation
+
+ * test/ziptest.rb: [no log message]
+
+2005-02-16 20:04 thomas
+
+ * NEWS, README, Rakefile: Improved documentation and added rdoc
+ task to Rakefile
+
+ * NEWS, Rakefile, lib/zip/zip.rb: [no log message]
+
+ * Rakefile, samples/example.rb, samples/example_filesystem.rb,
+ samples/gtkRubyzip.rb, samples/write_simple.rb,
+ samples/zipfind.rb, test/.cvsignore, test/gentestfiles.rb:
+ Improvements to Rakefile
+
+2005-02-15 23:35 thomas
+
+ * NEWS, TODO: [no log message]
+
+ * Rakefile, rubyzip.gemspec: Now uses Rake to build gem
+
+ * Rakefile: [no log message]
+
+ * lib/zip/zip.rb, test/.cvsignore, test/ziptest.rb, NEWS: Fixed
+ compatibility issue with ruby 1.8.2. Migrated test suite to
+ Test::Unit
+
+ * NEWS, lib/zip/ioextras.rb, lib/zip/stdrubyext.rb,
+ lib/zip/tempfile_bugfixed.rb, lib/zip/zip.rb,
+ lib/zip/zipfilesystem.rb, lib/zip/ziprequire.rb, test/.cvsignore,
+ test/file1.txt, test/file1.txt.deflatedData, test/file2.txt,
+ test/gentestfiles.rb, test/ioextrastest.rb,
+ test/notzippedruby.rb, test/rubycode.zip, test/rubycode2.zip,
+ test/stdrubyexttest.rb, test/testDirectory.bin,
+ test/zipWithDirs.zip, test/zipfilesystemtest.rb,
+ test/ziprequiretest.rb, test/ziptest.rb, test/data/.cvsignore,
+ test/data/file1.txt, test/data/file1.txt.deflatedData,
+ test/data/file2.txt, test/data/notzippedruby.rb,
+ test/data/rubycode.zip, test/data/rubycode2.zip,
+ test/data/testDirectory.bin, test/data/zipWithDirs.zip: Changed
+ directory structure
+
+2005-02-13 22:44 thomas
+
+ * Rakefile, TODO: [no log message]
+
+ * rubyzip.gemspec: [no log message]
+
+ * install.rb: Made install.rb independent of the current path
+ (fixes bug reported by Drew Robinson)
+
+2004-12-12 11:22 thomas
+
+ * NEWS, TODO, samples/write_simple.rb: Fixed 'version needed to
+ extract'-field wrong in local headers
+
+2004-05-02 15:17 thomas
+
+ * rubyzip.gemspec: Added gemspec contributed by Chad Fowler
+
+2004-04-02 07:25 thomas
+
+ * NEWS: Fix for FreeBSD 4.9
+
+2004-03-29 00:28 thomas
+
+ * NEWS: [no log message]
+
+2004-03-28 17:59 thomas
+
+ * NEWS: [no log message]
+
+2004-03-27 16:09 thomas
+
+ * test/stdrubyexttest.rb: Patch for stdrubyext.rb from Nobu Nakada
+
+ * test/: ioextrastest.rb, stdrubyexttest.rb: converted some files
+ to unix line-endings
+
+2004-03-25 16:34 thomas
+
+ * NEWS, install.rb: Significantly reduced memory footprint when
+ modifying zip files
+
+2004-03-16 18:20 thomas
+
+ * install.rb, test/alltests.rb, test/ioextrastest.rb,
+ test/stdrubyexttest.rb, test/ziptest.rb: IO utility classes moved
+ to new file ioextras.rb. Tests moved to new file ioextrastest.rb
+
+2004-02-27 13:21 thomas
+
+ * NEWS: Optimization to avoid decompression and recompression
+
+2004-01-30 16:17 thomas
+
+ * NEWS: [no log message]
+
+ * README, test/zipfilesystemtest.rb, test/ziptest.rb: Applied
+ extra-field patch
+
+2003-12-13 16:57 thomas
+
+ * TODO: [no log message]
+
+2003-12-10 00:25 thomas
+
+ * test/ziptest.rb: (Temporary) fix to bug reported by Takashi Sano
+
+2003-08-23 09:42 thomas
+
+ * test/ziptest.rb, NEWS: Fixed ZipFile.get_ouput_stream bug - data
+ was never written to zip
+
+2003-08-21 16:05 thomas
+
+ * install.rb: [no log message]
+
+ * alltests.rb, stdrubyexttest.rb, zipfilesystemtest.rb,
+ ziprequiretest.rb, ziptest.rb, test/alltests.rb,
+ test/stdrubyexttest.rb, test/zipfilesystemtest.rb,
+ test/ziprequiretest.rb, test/ziptest.rb: Moved all test ruby
+ files to test/
+
+ * NEWS, install.rb, stdrubyext.rb, stdrubyexttest.rb, zip.rb,
+ zipfilesystem.rb, zipfilesystemtest.rb, ziprequire.rb,
+ ziprequiretest.rb, ziptest.rb, samples/example.rb,
+ samples/example_filesystem.rb, samples/gtkRubyzip.rb,
+ samples/zipfind.rb: Moved all production source files to zip/ so
+ they are in the same dir as when they are installed
+
+ * NEWS, TODO, alltests.rb: [no log message]
+
+ * filearchive.rb, filearchivetest.rb, fileutils.rb: Removed
+ filearchive.rb, filearchivetest.rb and fileutils.rb
+
+ * samples/.cvsignore, samples/example_filesystem.rb, zip.rb,
+ samples/example_filesystem.rb: Added
+ samples/example_filesystem.rb. Fixed Tempfile creation for
+ entries created with get_output_stream where entries were in a
+ subdirectory
+
+ * zip.rb, ziptest.rb: Fixed mkdir bug. ZipFile.mkdir didn't work if
+ the zipfile doesn't exist already
+
+ * ziptest.rb: [no log message]
+
+ * TODO, zipfilesystemtest.rb: Globbing test placeholder commented
+ out
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented ZipFsDir.new
+ and open
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented DirFsIterator
+ and tests
+
+2003-08-20 22:50 thomas
+
+ * NEWS, TODO: [no log message]
+
+ * zipfilesystemtest.rb: [no log message]
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsDir.foreach, ZipFsDir.entries now reimplemented in terms of
+ it
+
+ * README: [no log message]
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: [no log message]
+
+ * zipfilesystem.rb: All access from ZipFsFile and ZipFsDir to
+ ZipFile is now routed through ZipFileNameMapper which has the
+ single responsibility of mapping entry/filenames
+
+ * alltests.rb, stdrubyext.rb, stdrubyexttest.rb: Added
+ stdrubyexttest.rb and added test test_select_map
+
+ * zipfilesystem.rb: ZipFsDir was in the wrong module. ZipFileSystem
+ now has a ctor that creates ZipFsDir and ZipFsFile instances,
+ instead of creating them lazily. It then passes the dir instance
+ to the file instance and vice versa
+
+ * zip.rb, zipfilesystem.rb, zipfilesystemtest.rb: ZipFsFile.open
+ honours chdir
+
+ * stdrubyext.rb, zip.rb, zipfilesystem.rb, zipfilesystemtest.rb,
+ ziptest.rb: Fixed ZipEntry::parent_as_string. Implemented
+ ZipFsDir.chdir, pwd and entries including test
+
+2003-08-19 15:44 thomas
+
+ * zip.rb, zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsDir.mkdir
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsDir.delete (and aliases rmdir and unlink)
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Another dummy
+ implementation and commented out a test for select() which can be
+ added later
+
+2003-08-18 20:40 thomas
+
+ * ziptest.rb: Honoured 1.8.0 Object.to_a deprecation warning
+
+ * zip.rb, ziptest.rb, samples/example.rb, samples/zipfind.rb:
+ Converted a few more names to ruby underscore style that I missed
+ with the automated processing the first time around
+
+ * zip.rb, zipfilesystem.rb, zipfilesystemtest.rb, ziptest.rb:
+ Implemented Zip::ZipFile.get_output_stream
+
+2003-08-17 18:28 thomas
+
+ * README, install.rb, stdrubyext.rb, zipfilesystem.rb,
+ zipfilesystemtest.rb: Updated README with Documentation section.
+ Updated install.rb. Fixed three tests that failed on 1.8.0.
+
+2003-08-14 05:40 thomas
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Added empty
+ implementations of atime and ctime
+
+2003-08-13 17:08 thomas
+
+ * simpledist.rb: Moved simpledist to a separate repository called
+ 'misc'
+
+ * NEWS: [no log message]
+
+ * stdrubyext.rb, zip.rb, zipfilesystem.rb, zipfilesystemtest.rb,
+ ziprequire.rb, ziprequiretest.rb, ziptest.rb, samples/example.rb,
+ samples/gtkRubyzip.rb, samples/zipfind.rb: Changed all method
+ names to the ruby convention underscore style
+
+ * alltests.rb, zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ a lot more of the stat methods. Mostly with dummy implementations
+ that return values that indicate that these features aren't
+ supported
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented more methods
+ and tests in zipfilesystem. Mostly empty methods as permissions
+ and file types other than files and directories are not supported
+
+ * install.rb, stdrubyext.rb, zip.rb, zipfilesystem.rb,
+ zipfilesystemtest.rb: Addd file stdrubyext.rb and moved the
+ modifications to std ruby classes to it. Refactored the ZipFsStat
+ tests and ZipFsStat. Added Module.forwardMessages and used it to
+ implement the forwarding of calls in ZipFsStat
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Added
+ Zip::ZipFsFile::ZipFsStat and started implementing it and its
+ methods
+
+ * zipfilesystem.rb, zipfilesystemtest.rb, ziptest.rb: Updated and
+ added missing copyright notices
+
+ * zip.rb, zipfilesystem.rb, zipfilesystemtest.rb: zipfilesystem.rb
+ is becoming big and not everyone will want to use that code.
+ Therefore zip.rb no longer requires it. Instead you must require
+ zipfilesystem.rb itself if you want to use it
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented dummy
+ permission test methods
+
+ * TODO, zip.rb, ziptest.rb: Merged from patch from Kristoffer
+ Lunden. Fixed more 1.8.0 incompatibilites - tests run on 1.8.0
+ now
+
+2003-08-12 19:18 thomas
+
+ * zip.rb: Get rid of 1.8.0 warning
+
+ * ziptest.rb: ruby 1.8.0 compatibility fix
+
+ * NEWS, zip.rb: ruby-zlib 0.6.0 compatibility fix
+
+2002-12-22 20:12 thomas
+
+ * zip.rb: [no log message]
+
+2002-09-16 22:11 thomas
+
+ * NEWS: [no log message]
+
+2002-09-15 17:16 thomas
+
+ * samples/zipfind.rb: [no log message]
+
+ * samples/zipfind.rb: [no log message]
+
+2002-09-14 22:59 thomas
+
+ * samples/zipfind.rb: Added simple zipfind script
+
+2002-09-13 23:53 thomas
+
+ * TODO: Added TODO about openmode for zip entries binary/ascii
+
+ * NEWS: ziptest now runs without errors with ruby-1.7.2-4 (Andy's
+ latest build)
+
+ * zip.rb, ziprequiretest.rb, ziptest.rb: ziptest now runs without
+ errors with ruby-1.7.2-4 (Andy's latest build)
+
+2002-09-12 00:20 thomas
+
+ * zipfilesystemtest.rb: Improved ZipFsFile.delete/unlink test
+
+ * test/.cvsignore: [no log message]
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.delete/unlink
+
+2002-09-11 22:22 thomas
+
+ * alltests.rb: [no log message]
+
+ * NEWS, zip.rb, zipfilesystem.rb, zipfilesystemtest.rb: Fixed
+ AbstractInputStream.each_line ignored its aSeparator argument.
+ Implemented more ZipFsFile methods
+
+ * zip.rb, zipfilesystem.rb, zipfilesystemtest.rb: ZipFileSystem is
+ now a module instead of a class, and is mixed into ZipFile,
+ instead of being made available as a property fileSystem
+
+2002-09-10 23:45 thomas
+
+ * NEWS: Updated NEWS file
+
+ * zip.rb: [no log message]
+
+ * NEWS, zip.rb, ziptest.rb: Fix bug: rewind should reset lineno.
+ Fix bug: Deflater.read uses separate buffer from produceInput
+ (feeding gets/readline etc)
+
+2002-09-09 23:48 thomas
+
+ * .cvsignore: [no log message]
+
+2002-09-09 22:55 uid26649
+
+ * zip.rb, ziptest.rb: Implemented ZipInputStream.rewind and
+ AbstractInputStream.lineno. Tests for both
+
+2002-09-09 20:31 thomas
+
+ * zip.rb, ziptest.rb: ZipInputStream and ZipOutstream (thru their
+ AbstractInputStream and AbstractOutputStream now lie about being
+ kind_of?(IO)
+
+2002-09-08 16:38 thomas
+
+ * zipfilesystemtest.rb: [no log message]
+
+ * filearchive.rb, filearchivetest.rb, zip.rb, ziptest.rb: Moved
+ String additions from filearchive.rb to zip.rb (and moved tests
+ along too to ziptest.rb). Added ZipEntry.parentAsString and
+ ZipEntrySet.parent
+
+ * ziptest.rb: Implemented ZipEntrySetTest.testDup and testCompound
+
+ * TODO, zip.rb, ziptest.rb: Replaced Array with EntrySet for
+ keeping entries in a zip file. Tagged repository before this
+ commit, so this change can be rolled back, if it stinks
+
+2002-09-07 20:21 thomas
+
+ * zip.rb, ziptest.rb: Implemented ZipEntry.<=>
+
+ * ziptest.rb: Removed unused code
+
+2002-08-11 15:14 thomas
+
+ * zip.rb, ziptest.rb: Made some changes to accomodate ruby 1.7.2
+
+2002-07-27 15:25 thomas
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented ZipFsFile.new
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.pipe
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.link
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.symlink
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.readlink, wrapped ZipFileSystem class in Zip module
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.zero?
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented test for
+ ZipFsFile.directory?
+
+2002-07-26 23:56 thomas
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.socket?
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.join
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.ftype
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.blockdev?
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.size? (slightly different from size)
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.split
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implemented
+ ZipFsFile.symlink?
+
+ * alltests.rb, zip.rb, zipfilesystem.rb, zipfilesystemtest.rb:
+ Implemented ZipFsFile.mtime
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: Implement ZipFsFile.file?
+
+ * zip.rb, ziptest.rb: Implemented ZipEntry.file?
+
+ * alltests.rb, filearchive.rb, filearchivetest.rb, zip.rb,
+ zipfilesystem.rb, zipfilesystemtest.rb, ziprequire.rb,
+ ziptest.rb: Implemented ZipFileSystem::ZipFsFile.size
+
+ * zipfilesystem.rb, zipfilesystemtest.rb: [no log message]
+
+ * test/zipWithDirs.zip: Changed zipWithDirs.zip so all the entries
+ in it have unix file endings
+
+ * alltests.rb, zip.rb, zipfilesystem.rb, zipfilesystemtest.rb:
+ Started implementing ZipFileSystem
+
+ * test/zipWithDirs.zip: Added a zip file for testing with a
+ directory structure
+
+2002-07-22 21:40 thomas
+
+ * TODO: [no log message]
+
+ * TODO: [no log message]
+
+2002-07-21 18:20 thomas
+
+ * NEWS: [no log message]
+
+ * TODO: Updated TODO with a refactoring idea for FileArchive
+
+ * filearchive.rb, filearchivetest.rb: Added some FileArchiveAdd
+ tests and cleaned up some of the FileArchive tests. extract and
+ add now have individual test fixtures.
+
+ * filearchive.rb, filearchivetest.rb: Added tests for extract
+ called with regex src arg and Enumerable src arg
+
+ * filearchivetest.rb: Added test for continueOnExistsProc when
+ extracting from a file archive
+
+2002-07-20 17:13 thomas
+
+ * TODO, filearchivetest.rb, fileutils.rb, ziptest.rb,
+ test/.cvsignore: Added (failing) tests for FileArchive.add, added
+ code for creating test files for FileArchive.add tests. Added
+ fileutils.rb, which is borrowed from ruby 1.7.2
+
+ * filearchive.rb, filearchivetest.rb: [no log message]
+
+ * filearchivetest.rb: Added tests for String extensions
+
+ * alltests.rb, ziprequiretest.rb, ziptest.rb: [no log message]
+
+ * install.rb: [no log message]
+
+ * TODO: Updated TODO
+
+ * filearchive.rb, filearchivetest.rb: All FileArchive.extract tests
+ run
+
+2002-07-19 23:11 thomas
+
+ * filearchive.rb, filearchivetest.rb: [no log message]
+
+ * filearchivetest.rb: [no log message]
+
+ * filearchive.rb, filearchivetest.rb: [no log message]
+
+ * filearchive.rb, filearchivetest.rb, zip.rb: [no log message]
+
+2002-07-08 13:41 thomas
+
+ * TODO: [no log message]
+
+2002-06-11 19:47 thomas
+
+ * filearchive.rb, filearchivetest.rb, zip.rb, ziptest.rb: [no log
+ message]
+
+2002-05-25 00:41 thomas
+
+ * simpledist.rb: Added hackish script for creating dist files
+
+2002-04-30 21:22 thomas
+
+ * TODO: [no log message]
+
+ * filearchive.rb, filearchivetest.rb: [no log message]
+
+ * filearchive.rb, filearchivetest.rb: Improved testing and wrote
+ some of the skeleton of extract. Still to do: Fix glob, so it
+ returns a hashmap instead of a list. The map will need to map the
+ full entry name to the last part of the name (which is only
+ really interesting for recursively extracted entries, otherwise
+ it is just the name). Glob.expandPathList should also output
+ directories with a trailing slash, which is doesn't right now.
+
+ * filearchive.rb, filearchivetest.rb: Implemented the first few
+ tests for FileArchive
+
+2002-04-24 22:06 thomas
+
+ * ziprequire.rb, ziprequiretest.rb: Appended copyright message to
+ ziprequire.rb and ziprequiretest.rb
+
+ * zip.rb: Made ZipEntry tolerate invalid dates
+
+2002-04-21 00:57 thomas
+
+ * NEWS, TODO, zip.rb, ziptest.rb: Read and write entry modification
+ date/time correctly
+
+2002-04-20 02:44 thomas
+
+ * ziprequiretest.rb, test/rubycode2.zip: improved ZipRequireTest
+
+ * ziprequire.rb: Made a warning go away
+
+ * ziprequire.rb, ziprequiretest.rb, test/notzippedruby.rb,
+ test/rubycode.zip: Fixed a bug in ziprequire. Added
+ ziprequiretest.rb and test data files
+
+2002-04-19 22:43 thomas
+
+ * zip.rb, ziptest.rb: Added recursion support to Glob module
+
+2002-04-18 21:37 thomas
+
+ * NEWS, TODO, zip.rb, ziptest.rb: Added Glob module and GlobTest
+ unit test suite. This module provides the functionality to expand
+ a 'glob pattern' given a list of files - Next step is to use this
+ module in ZipFile
+
+2002-04-01 22:55 thomas
+
+ * NEWS: [no log message]
+
+ * TODO, zip.rb, ziprequire.rb: Added ziprequire.rb which contains a
+ proof-of-concept implementation of a require implementation that
+ can load ruby modules from a zip file. Needs unit tests and
+ polish.
+
+2002-03-31 01:13 thomas
+
+ * README: [no log message]
+
+2002-03-30 16:14 thomas
+
+ * TODO: [no log message]
+
+ * .cvsignore, README, zip.rb: Added rdoc markup (only #:nodoc:all
+ modifiers) to zip.rb. Made README 'RDoc compliant'
+
+2002-03-29 23:29 thomas
+
+ * TODO: [no log message]
+
+ * example.rb, samples/.cvsignore, samples/example.rb,
+ samples/gtkRubyzip.rb: Moved example.rb to samples/. Added
+ another sample gtkRubyzip.rb
+
+ * NEWS, TODO, TODO: [no log message]
+
+ * .cvsignore, file1.txt, file1.txt.deflatedData, testDirectory.bin,
+ ziptest.rb, test/.cvsignore, test/file1.txt,
+ test/file1.txt.deflatedData, test/file2.txt,
+ test/testDirectory.bin: Added test/ directory and moved the
+ manually created test data files into it. Changed ziptest.rb so
+ it runs in test/ directory
+
+ * TODO: [no log message]
+
+ * NEWS, zip.rb, ziptest.rb: Don't decompress and recompress zip
+ entries when changing zip file
+
+ * zip.rb: Performance optimization: Only write new ZipFile, if it
+ has been changed. The test suite runs in half the time now.
+
+2002-03-28 22:12 thomas
+
+ * TODO: [no log message]
+
+2002-03-23 17:31 thomas
+
+ * TODO: [no log message]
+
+2002-03-22 22:47 thomas
+
+ * NEWS: [no log message]
+
+ * NEWS, TODO: [no log message]
+
+ * ziptest.rb: Found the tests that didn't use blocks to make sure
+ input streams are closed as soon as they arent used anymore and
+ got rid of the GC.start
+
+ * ziptest.rb: All tests run on windows ruby 1.6.6
+
+ * zip.rb, ziptest.rb: Windows fixes: Fixed ZipFile.initialize which
+ needed to open zipfile file in binary mode. Added another
+ workaround for the return value from File.open(name) where name
+ is the name of a directory - ruby returns different exceptions in
+ linux, win/cygwin and windows. A number of tests failed because
+ in windows you cant delete a file that is open. Fixed by changing
+ ziptest.rb to use ZipInputStream.getInputStream with blocks a few
+ places. There is a hack in CommanZipFileFixture.setup where the
+ GC is explicitly invoked. Should be fixed with blocks instead.
+ The only currently failing test fails because the test data
+ creation fails to add a comment to 4entry.zip, because echo eats
+ the remainder of the line including the pipe character and the
+ following zip -z 4 entry.zip command
+
+2002-03-21 22:18 thomas
+
+ * NEWS: [no log message]
+
+ * NEWS, README, TODO, install.rb: Added install.rb
+
+ * ziptest.rb: [no log message]
+
+ * NEWS, TODO: [no log message]
+
+ * .cvsignore, TODO, zip.rb, ziptest.rb: Added
+ test_extractDirectoryExistsAsFileOverwrite and fixed to pass
+
+ * zip.rb, ziptest.rb: Extraction of directory entries is now
+ supported
+
+2002-03-20 21:59 thomas
+
+ * NEWS: [no log message]
+
+ * COPYING, README, README.txt: Removed COPYING, renamed README.txt
+ to README. Updated README
+
+ * example.rb: Fixed example.rb added example that shows zip file
+ manipulation with Zip::ZipFile
+
+ * .cvsignore: [no log message]
+
+ * TODO, zip.rb, ziptest.rb: Directories can now be added (not
+ recursively, the directory entry itself. Directories are
+ recognized by a empty entries with a trailing /. The purpose of
+ storing them explicitly in the zip file is to be able to store
+ permission and ownership information
+
+ * TODO, zip.rb, ziptest.rb: zip.rb depended on ftools but it was
+ only included in ziptest.rb
+
+ * zip.rb, ziptest.rb: ZipError is now a subclass of StandardError
+ instead of RuntimeError. ZipError now has several subclasses.
+
+2002-03-19 22:26 thomas
+
+ * TODO: [no log message]
+
+ * TODO, ziptest.rb: Unit test ZipFile.getInputStream with block
+
+ * TODO, zip.rb, ziptest.rb: Unit test for adding new entry with
+ name that already exists in archive, and fixed to pass test
+
+ * TODO, zip.rb, ziptest.rb: Added unit tests for rename to existing
+ entry
+
+ * TODO: [no log message]
+
+ * TODO, zip.rb, ziptest.rb: Unit test calling ZipFile.extract with
+ block
+
+2002-03-18 21:06 thomas
+
+ * TODO: [no log message]
+
+ * zip.rb, ziptest.rb: ZipFile#commit now reinitializes ZipFile.
+
+ * TODO, zip.rb, ziptest.rb: Refactoring:
+
+ Collapsed ZipEntry and ZipStreamableZipEntry into ZipEntry.
+
+ Collapsed BasicZipFile and ZipFile into ZipFile.
+
+ * zip.rb: Removed method that was never called
+
+2002-03-17 22:33 thomas
+
+ * TODO: [no log message]
+
+ * ziptest.rb: Run tests with =true as default
+
+ * NEWS, TODO, zip.rb, ziptest.rb: Now runs with -w switch without
+ warnings
+
+ * .cvsignore: [no log message]
+
+ * zip.rb, ziptest.rb: Down to one failing test
+
+ * zip.rb, ziptest.rb: [no log message]
+
+ * TODO, zip.rb, ziptest.rb: [no log message]
+
+2002-02-25 19:42 thomas
+
+ * TODO: Added more todos
+
+2002-02-23 15:51 thomas
+
+ * zip.rb: [no log message]
+
+ * zip.rb, ziptest.rb: [no log message]
+
+ * zip.rb, ziptest.rb: [no log message]
+
+2002-02-03 18:47 thomas
+
+ * ziptest.rb: [no log message]
+
+2002-02-02 15:58 thomas
+
+ * example.rb, zip.rb, ziptest.rb: [no log message]
+
+ * .cvsignore: [no log message]
+
+ * example.rb, zip.rb, ziptest.rb: Renamed SimpleZipFile to
+ BasicZipFile
+
+ * TODO: [no log message]
+
+ * ziptest.rb: More test cases - all of them failing, so now there
+ are 18 failing test cases. Three more test cases to implement,
+ then it is time for the production code
+
+2002-02-01 21:49 thomas
+
+ * ziptest.rb: [no log message]
+
+ * ziptest.rb: Also run SimpleZipFile tests for ZipFile.
+
+ * example.rb, zip.rb, ziptest.rb: ZipFile renamed to SimpleZipFile.
+ The new ZipFile will have many more methods that are useful for
+ managing archives.
+
+2002-01-29 20:30 thomas
+
+ * TODO: [no log message]
+
+2002-01-26 00:18 thomas
+
+ * NEWS: [no log message]
+
+ * ziptest.rb: In unit test: work around ruby/cygwin weirdness. You
+ get an Errno::EEXISTS instead of an Errno::EISDIR if you try to
+ open a file for writing that is a directory.
+
+ * ziptest.rb: Fixed test that failed on windows because of CRLF
+ line ending
+
+2002-01-25 23:58 thomas
+
+ * ziptest.rb: [no log message]
+
+ * .cvsignore, example.rb, zip.rb: Fixed bug reading from empty
+ deflated entry in zip file
+
+ * .cvsignore: [no log message]
+
+ * ziptest.rb: [no log message]
+
+ * NEWS, README.txt, zip.rb, ziptest.rb: Zip write support is now
+ fully functional in the form of ZipOutputStream.
+
+ * zip.rb, ziptest.rb: [no log message]
+
+ * zip.rb, ziptest.rb: [no log message]
+
+2002-01-20 16:00 thomas
+
+ * zip.rb, ziptest.rb: Added Deflater and DeflaterTest.
+
+ * .cvsignore: [no log message]
+
+ * .cvsignore: Added .cvsignore file
+
+ * zip.rb, ziptest.rb: Added ZipEntry.writeCDirEntry and misc minor
+ fixes
+
+2002-01-19 23:28 thomas
+
+ * example.rb, zip.rb, ziptest.rb: NOTICE: Not all tests run!!
+
+ ZipOutputStream in progress
+
+ Wrapped rubyzip in namespace module Zip.
+
+2002-01-17 18:52 thomas
+
+ * ziptest.rb: Fail nicely if the user doesn't have info-zip
+ compatible zip in the path
+
+2002-01-10 18:02 thomas
+
+ * zip.rb: Adjusted chunk size to 32k after a few perf measurements
+
+2002-01-09 22:10 thomas
+
+ * README.txt: License now same as rubys, not just GPL
+
+2002-01-06 00:19 thomas
+
+ * README.txt: [no log message]
+
+2002-01-05 23:09 thomas
+
+ * NEWS, README.txt, NEWS: Updated NEWS file
+
+ * README.txt, zip.rb, ziptest.rb, zlib.c.diff: Added tests for
+ decompressors and a tests for ZipLocalEntry,
+ ZipCentralDirectoryEntry and ZipCentralDirectory for handling of
+ corrupt data
+
+ * file1.txt.deflatedData: deflated data extracted from a zip file.
+ contains file1.txt
+
+ * zip.rb: Changed references to Inflate to Zlib::inflate for
+ compatibility with ruby-zlib-0.5
+
+ * README.txt, zip.rb, ziptest.rb: [no log message]
+
+ * example.rb, NEWS: [no log message]
+
+ * COPYING, README.txt: [no log message]
+
+ * ziptest.rb: Fixed problem with test file creation
+
+ * README.txt: Updated README.txt
+
+ * zip.rb, ziptest.rb: ZipFile now works
+
+2002-01-04 21:51 thomas
+
+ * testDirectory.bin, zip.rb, ziptest.rb:
+ ZipCentralDirectoryEntryTest now runs
+
+ * ziptest.rb: Changed
+ ZIpLocalNEtryTest::test_ReadLocalEntryHeaderOfFirstTestZipEntry
+ so it works on both unix too. It only worked on windows because
+ the test made assumptions about the compressed size and crc of an
+ entry, but that differs depending on the OS because of the CRLF
+ thing.
+
+ * README.txt: Added note about zlib.c patch
+
+2002-01-02 18:48 thomas
+
+ * README.txt, example.rb, file1.txt, zip.rb, ziptest.rb,
+ zlib.c.diff: initial
+
+ * README.txt, example.rb, file1.txt, zip.rb, ziptest.rb,
+ zlib.c.diff: Initial revision
+
144 NEWS
@@ -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 README
@@ -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 Rakefile
@@ -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 TODO
@@ -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 install.rb
@@ -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)
+}
155 lib/zip/ioextras.rb
@@ -0,0 +1,155 @@
+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
+ module FakeIO
+ def kind_of?(object)
+ object == IO || super
+ end
+ end
+
+ # Implements many of the convenience methods of IO
+ # such as gets, getc, readline and readlines
+ # depends on: input_finished?, produce_input and read
+ module AbstractInputStream
+ include Enumerable
+ include FakeIO
+
+ def initialize
+ super
+ @lineno = 0
+ @outputBuffer = ""
+ end
+
+ 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 = $/)
+ retVal = []
+ each_line(aSepString) { |line| retVal << line }
+ return retVal
+ end
+
+ def gets(aSepString=$/)
+ @lineno = @lineno.next
+ return read if aSepString == nil
+ aSepString="#{$/}#{$/}" if aSepString == ""
+
+ bufferIndex=0
+ while ((matchIndex = @outputBuffer.index(aSepString, bufferIndex)) == nil)
+ bufferIndex=@outputBuffer.length
+ if input_finished?
+ return @outputBuffer.empty? ? nil : flush
+ end
+ @outputBuffer << produce_input
+ end
+ sepIndex=matchIndex + aSepString.length
+ return @outputBuffer.slice!(0...sepIndex)
+ end
+
+ def flush
+ retVal=@outputBuffer
+ @outputBuffer=""
+ return retVal
+ end
+
+ def readline(aSepString = $/)
+ retVal = gets(aSepString)
+ raise EOFError if retVal == nil
+ return retVal
+ end
+
+ def each_line(aSepString = $/)
+ while true
+ yield readline(aSepString)
+ end
+ rescue EOFError
+ end
+
+ alias_method :each, :each_line
+ end
+
+
+ # Implements many of the output convenience methods of IO.
+ # relies on <<
+ module AbstractOutputStream
+ include FakeIO
+
+ def write(data)
+ self << data
+ data.to_s.length
+ end
+
+
+ def print(*params)
+ self << params.to_s << $\.to_s
+ end
+
+ def printf(aFormatString, *params)
+ self << sprintf(aFormatString, *params)
+ end
+
+ def putc(anObject)
+ self << case anObject
+ when Fixnum then anObject.chr
+ when String then anObject
+ else raise TypeError, "putc: Only Fixnum and String supported"
+ end
+ anObject
+ end
+
+ def puts(*params)
+ params << "\n" if params.empty?
+ params.flatten.each {
+ |element|
+ val = element.to_s
+ self << val
+ self << "\n" unless val[-1,1] == "\n"
+ }
+ end
+
+ end
+
+end # IOExtras namespace module
+
+
+
+# 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.
111 lib/zip/stdrubyext.rb
@@ -0,0 +1,111 @@
+unless Enumerable.method_defined?(:inject)
+ module Enumerable #:nodoc:all
+ def inject(n = 0)
+ each { |value| n = yield(n, value) }
+ n
+ end
+ end
+end
+
+module Enumerable #:nodoc:all
+ # returns a new array of all the return values not equal to nil
+ # This implementation could be faster
+ def select_map(&aProc)
+ map(&aProc).reject { |e| e.nil? }
+ end
+end
+
+unless Object.method_defined?(:object_id)
+ class Object #:nodoc:all
+ # Using object_id which is the new thing, so we need
+ # to make that work in versions prior to 1.8.0
+ alias object_id id
+ end
+end
+
+unless File.respond_to?(:read)
+ class File # :nodoc:all
+ # singleton method read does not exist in 1.6.x
+ def self.read(fileName)
+ open(fileName) { |f| f.read }
+ end
+ end
+end
+
+class String #:nodoc:all
+ def starts_with(aString)
+ rindex(aString, 0) == 0
+ end
+
+ def ends_with(aString)
+ index(aString, -aString.size)
+ end
+
+ def ensure_end(aString)
+ ends_with(aString) ? self : self + aString
+ end
+
+ def lchop
+ slice(1, length)
+ end
+end
+
+class Time #:nodoc:all
+
+ #MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
+ #
+ # Register CX, the Time:
+ # Bits 0-4 2 second increments (0-29)
+ # Bits 5-10 minutes (0-59)
+ # bits 11-15 hours (0-24)
+ #
+ # Register DX, the Date:
+ # Bits 0-4 day (1-31)
+ # bits 5-8 month (1-12)
+ # bits 9-15 year (four digit year minus 1980)
+
+
+ def to_binary_dos_time
+ (sec/2) +
+ (min << 5) +
+ (hour << 11)
+ end
+
+ def to_binary_dos_date
+ (day) +
+ (month << 5) +
+ ((year - 1980) << 9)
+ end
+
+ # Dos time is only stored with two seconds accuracy
+ def dos_equals(other)
+ to_i/2 == other.to_i/2
+ end
+
+ def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
+ second = 2 * ( 0b11111 & binaryDosTime)
+ minute = ( 0b11111100000 & binaryDosTime) >> 5
+ hour = (0b1111100000000000 & binaryDosTime) >> 11
+ day = ( 0b11111 & binaryDosDate)
+ month = ( 0b111100000 & binaryDosDate) >> 5
+ year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
+ begin
+ return Time.local(year, month, day, hour, minute, second)
+ end
+ end
+end
+
+class Module #:nodoc:all
+ def forward_message(forwarder, *messagesToForward)
+ methodDefs = messagesToForward.map {
+ |msg|
+ "def #{msg}; #{forwarder}(:#{msg}); end"
+ }
+ module_eval(methodDefs.join("\n"))
+ 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.
195 lib/zip/tempfile_bugfixed.rb
@@ -0,0 +1,195 @@
+#
+# tempfile - manipulates temporary files
+#
+# $Id: tempfile_bugfixed.rb,v 1.2 2005/02/19 20:30:33 thomas Exp $
+#
+
+require 'delegate'
+require 'tmpdir'
+
+module BugFix #:nodoc:all
+
+# A class for managing temporary files. This library is written to be
+# thread safe.
+class Tempfile < DelegateClass(File)
+ MAX_TRY = 10
+ @@cleanlist = []
+
+ # Creates a temporary file of mode 0600 in the temporary directory
+ # whose name is basename.pid.n and opens with mode "w+". A Tempfile
+ # object works just like a File object.
+ #
+ # If tmpdir is omitted, the temporary directory is determined by
+ # Dir::tmpdir provided by 'tmpdir.rb'.
+ # When $SAFE > 0 and the given tmpdir is tainted, it uses
+ # /tmp. (Note that ENV values are tainted by default)
+ def initialize(basename, tmpdir=Dir::tmpdir)
+ if $SAFE > 0 and tmpdir.tainted?
+ tmpdir = '/tmp'
+ end
+
+ lock = nil
+ n = failure = 0
+
+ begin
+ Thread.critical = true
+
+ begin
+ tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
+ lock = tmpname + '.lock'
+ n += 1
+ end while @@cleanlist.include?(tmpname) or
+ File.exist?(lock) or File.exist?(tmpname)
+
+ Dir.mkdir(lock)
+ rescue
+ failure += 1
+ retry if failure < MAX_TRY
+ raise "cannot generate tempfile `%s'" % tmpname
+ ensure
+ Thread.critical = false
+ end
+
+ @data = [tmpname]
+ @clean_proc = Tempfile.callback(@data)
+ ObjectSpace.define_finalizer(self, @clean_proc)
+
+ @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
+ @tmpname = tmpname
+ @@cleanlist << @tmpname
+ @data[1] = @tmpfile
+ @data[2] = @@cleanlist
+
+ super(@tmpfile)
+
+ # Now we have all the File/IO methods defined, you must not
+ # carelessly put bare puts(), etc. after this.
+
+ Dir.rmdir(lock)
+ end
+
+ # Opens or reopens the file with mode "r+".
+ def open
+ @tmpfile.close if @tmpfile
+ @tmpfile = File.open(@tmpname, 'r+')
+ @data[1] = @tmpfile
+ __setobj__(@tmpfile)
+ end
+
+ def _close # :nodoc:
+ @tmpfile.close if @tmpfile
+ @data[1] = @tmpfile = nil
+ end
+ protected :_close
+
+ # Closes the file. If the optional flag is true, unlinks the file
+ # after closing.
+ #
+ # If you don't explicitly unlink the temporary file, the removal
+ # will be delayed until the object is finalized.
+ def close(unlink_now=false)
+ if unlink_now
+ close!
+ else
+ _close
+ end
+ end
+
+ # Closes and unlinks the file.
+ def close!
+ _close
+ @clean_proc.call
+ ObjectSpace.undefine_finalizer(self)
+ end
+
+ # Unlinks the file. On UNIX-like systems, it is often a good idea
+ # to unlink a temporary file immediately after creating and opening
+ # it, because it leaves other programs zero chance to access the
+ # file.
+ def unlink
+ # keep this order for thread safeness
+ File.unlink(@tmpname) if File.exist?(@tmpname)
+ @@cleanlist.delete(@tmpname) if @@cleanlist
+ end
+ alias delete unlink
+
+ if RUBY_VERSION > '1.8.0'
+ def __setobj__(obj)
+ @_dc_obj = obj
+ end
+ else
+ def __setobj__(obj)
+ @obj = obj
+ end
+ end
+
+ # Returns the full path name of the temporary file.
+ def path
+ @tmpname
+ end
+
+ # Returns the size of the temporary file. As a side effect, the IO
+ # buffer is flushed before determining the size.
+ def size
+ if @tmpfile
+ @tmpfile.flush
+ @tmpfile.stat.size
+ else
+ 0
+ end
+ end
+ alias length size
+
+ class << self
+ def callback(data) # :nodoc:
+ pid = $$
+ lambda{
+ if pid == $$
+ path, tmpfile, cleanlist = *data
+
+ print "removing ", path, "..." if $DEBUG
+
+ tmpfile.close if tmpfile
+
+ # keep this order for thread safeness
+ File.unlink(path) if File.exist?(path)
+ cleanlist.delete(path) if cleanlist
+
+ print "done\n" if $DEBUG
+ end
+ }
+ end
+
+ # If no block is given, this is a synonym for new().
+ #
+ # If a block is given, it will be passed tempfile as an argument,
+ # and the tempfile will automatically be closed when the block
+ # terminates. In this case, open() returns nil.
+ def open(*args)
+ tempfile = new(*args)
+
+ if block_given?
+ begin
+ yield(tempfile)
+ ensure
+ tempfile.close
+ end
+
+ nil
+ else
+ tempfile
+ end
+ end
+ end
+end
+
+end # module BugFix
+if __FILE__ == $0
+# $DEBUG = true
+ f = Tempfile.new("foo")
+ f.print("foo\n")
+ f.close
+ f.open
+ p f.gets # => "foo\n"
+ f.close!
+end
1,847 lib/zip/zip.rb
@@ -0,0 +1,1847 @@
+require 'delegate'
+require 'singleton'
+require 'tempfile'
+require 'ftools'
+require 'stringio'
+require 'zlib'
+require 'zip/stdrubyext'
+require 'zip/ioextras'
+
+if Tempfile.superclass == SimpleDelegator
+ require 'zip/tempfile_bugfixed'
+ Tempfile = BugFix::Tempfile
+end
+
+module Zlib #:nodoc:all
+ if ! const_defined? :MAX_WBITS
+ MAX_WBITS = Zlib::Deflate.MAX_WBITS
+ end
+end
+
+module Zip
+
+ VERSION = '0.9.1'
+
+ RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i
+
+ RUNNING_ON_WINDOWS = /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
+
+ # Ruby 1.7.x compatibility
+ # In ruby 1.6.x and 1.8.0 reading from an empty stream returns
+ # an empty string the first time and then nil.
+ # not so in 1.7.x
+ EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST = RUBY_MINOR_VERSION != 7
+
+ # ZipInputStream is the basic class for reading zip entries in a
+ # zip file. It is possible to create a ZipInputStream object directly,
+ # passing the zip file name to the constructor, but more often than not
+ # the ZipInputStream will be obtained from a ZipFile (perhaps using the
+ # ZipFileSystem interface) object for a particular entry in the zip
+ # archive.
+ #
+ # A ZipInputStream inherits IOExtras::AbstractInputStream in order
+ # to provide an IO-like interface for reading from a single zip
+ # entry. Beyond methods for mimicking an IO-object it contains
+ # the method get_next_entry for iterating through the entries of
+ # an archive. get_next_entry returns a ZipEntry object that describes
+ # the zip entry the ZipInputStream is currently reading from.
+ #
+ # Example that creates a zip archive with ZipOutputStream and reads it
+ # back again with a ZipInputStream.
+ #
+ # require 'zip/zip'
+ #
+ # Zip::ZipOutputStream::open("my.zip") {
+ # |io|
+ #
+ # io.put_next_entry("first_entry.txt")
+ # io.write "Hello world!"
+ #
+ # io.put_next_entry("adir/first_entry.txt")
+ # io.write "Hello again!"
+ # }
+ #
+ #
+ # Zip::ZipInputStream::open("my.zip") {
+ # |io|
+ #
+ # while (entry = io.get_next_entry)
+ # puts "Contents of #{entry.name}: '#{io.read}'"
+ # end
+ # }
+ #
+ # java.util.zip.ZipInputStream is the original inspiration for this
+ # class.
+
+ class ZipInputStream
+ include IOExtras::AbstractInputStream
+
+ # Opens the indicated zip file. An exception is thrown
+ # if the specified offset in the specified filename is
+ # not a local zip entry header.
+ def initialize(filename, offset = 0)
+ super()
+ @archiveIO = File.open(filename, "rb")
+ @archiveIO.seek(offset, IO::SEEK_SET)
+ @decompressor = NullDecompressor.instance
+ @currentEntry = nil
+ end
+
+ def close
+ @archiveIO.close
+ end
+
+ # Same as #initialize but if a block is passed the opened
+ # stream is passed to the block and closed when the block
+ # returns.
+ def ZipInputStream.open(filename)
+ return new(filename) unless block_given?
+
+ zio = new(filename)
+ yield zio
+ ensure
+ zio.close if zio
+ end
+
+ # Returns a ZipEntry object. It is necessary to call this
+ # method on a newly created ZipInputStream before reading from
+ # the first entry in the archive. Returns nil when there are
+ # no more entries.
+
+ def get_next_entry
+ @archiveIO.seek(@currentEntry.next_header_offset,
+ IO::SEEK_SET) if @currentEntry
+ open_entry
+ end
+
+ # Rewinds the stream to the beginning of the current entry
+ def rewind
+ return if @currentEntry.nil?
+ @lineno = 0
+ @archiveIO.seek(@currentEntry.localHeaderOffset,
+ IO::SEEK_SET)
+ open_entry
+ end
+
+ # Modeled after IO.sysread
+ def sysread(numberOfBytes = nil, buf = nil)
+ @decompressor.sysread(numberOfBytes, buf)
+ end
+
+ def eof
+ @outputBuffer.empty? && @decompressor.eof
+ end
+ alias :eof? :eof
+
+ protected
+
+ def open_entry
+ @currentEntry = ZipEntry.read_local_entry(@archiveIO)
+ if (@currentEntry == nil)
+ @decompressor = NullDecompressor.instance
+ elsif @currentEntry.compression_method == ZipEntry::STORED
+ @decompressor = PassThruDecompressor.new(@archiveIO,
+ @currentEntry.size)
+ elsif @currentEntry.compression_method == ZipEntry::DEFLATED
+ @decompressor = Inflater.new(@archiveIO)
+ else
+ raise ZipCompressionMethodError,
+ "Unsupported compression method #{@currentEntry.compression_method}"
+ end
+ flush
+ return @currentEntry
+ end
+
+ def produce_input
+ @decompressor.produce_input
+ end
+
+ def input_finished?
+ @decompressor.input_finished?
+ end
+ end
+
+
+
+ class Decompressor #:nodoc:all
+ CHUNK_SIZE=32768
+ def initialize(inputStream)
+ super()
+ @inputStream=inputStream
+ end
+ end
+
+ class Inflater < Decompressor #:nodoc:all
+ def initialize(inputStream)
+ super
+ @zlibInflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
+ @outputBuffer=""
+ @hasReturnedEmptyString = ! EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST
+ end
+
+ def sysread(numberOfBytes = nil, buf = nil)
+ readEverything = (numberOfBytes == nil)
+ while (readEverything || @outputBuffer.length < numberOfBytes)
+ break if internal_input_finished?
+ @outputBuffer << internal_produce_input(buf)
+ end
+ return value_when_finished if @outputBuffer.length==0 && input_finished?
+ endIndex= numberOfBytes==nil ? @outputBuffer.length : numberOfBytes
+ return @outputBuffer.slice!(0...endIndex)
+ end
+
+ def produce_input
+ if (@outputBuffer.empty?)
+ return internal_produce_input
+ else
+ return @outputBuffer.slice!(0...(@outputBuffer.length))
+ end
+ end
+
+ # 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?
+ @outputBuffer.empty? && internal_input_finished?
+ end
+ alias :eof :input_finished?
+ alias :eof? :input_finished?
+
+ private
+
+ def internal_produce_input(buf = nil)
+ 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
+
+ def internal_input_finished?
+ @zlibInflater.finished?
+ end
+
+ # TODO: Specialize to handle different behaviour in ruby > 1.7.0 ?
+ def value_when_finished # mimic behaviour of ruby File object.
+ return nil if @hasReturnedEmptyString
+ @hasReturnedEmptyString=true
+ return ""
+ end
+ end
+
+ class PassThruDecompressor < Decompressor #:nodoc:all
+ def initialize(inputStream, charsToRead)
+ super inputStream
+ @charsToRead = charsToRead
+ @readSoFar = 0
+ @hasReturnedEmptyString = ! EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST
+ end
+
+ # TODO: Specialize to handle different behaviour in ruby > 1.7.0 ?
+ def sysread(numberOfBytes = nil, buf = nil)
+ if input_finished?
+ hasReturnedEmptyStringVal=@hasReturnedEmptyString
+ @hasReturnedEmptyString=true
+ return "" unless hasReturnedEmptyStringVal
+ return nil
+ end
+
+ if (numberOfBytes == nil || @readSoFar+numberOfBytes > @charsToRead)
+ numberOfBytes = @charsToRead-@readSoFar
+ end
+ @readSoFar += numberOfBytes
+ @inputStream.read(numberOfBytes, buf)
+ end
+
+ def produce_input
+ sysread(Decompressor::CHUNK_SIZE)
+ end
+
+ def input_finished?
+ (@readSoFar >= @charsToRead)
+ end
+ alias :eof :input_finished?
+ alias :eof? :input_finished?
+ end
+
+ class NullDecompressor #:nodoc:all
+ include Singleton
+ def sysread(numberOfBytes = nil, buf = nil)
+ nil
+ end
+
+ def produce_input
+ nil
+ end
+
+ def input_finished?
+ true
+ end
+
+ def eof
+ true
+ end
+ alias :eof? :eof
+ end
+
+ class NullInputStream < NullDecompressor #:nodoc:all
+ include IOExtras::AbstractInputStream
+ end
+
+ class ZipEntry
+ STORED = 0
+ 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,
+ :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 = "",
+ compressed_size = 0, crc = 0,
+ compression_method = ZipEntry::DEFLATED, size = 0,
+ time = Time.now)
+ super()
+ if name.starts_with("/")
+ raise ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
+ end
+ @localHeaderOffset = 0
+ @internalFileAttributes = 1
+ @externalFileAttributes = 0
+ @version = 52 # this library's version
+ @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,
+ @name, @size = zipfile, comment, compressed_size, crc,
+ extra, compression_method, name, size
+ @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
+ @extra = ZipExtraField.new(@extra.to_s)
+ end
+ end
+
+ def time
+ if @extra["UniversalTime"]
+ @extra["UniversalTime"].mtime
+ else
+ # Atandard time field in central directory has local time
+ # under archive creator. Then, we can't get timezone.
+ @time
+ end
+ end
+ alias :mtime :time
+
+ def time=(aTime)
+ unless @extra.member?("UniversalTime")
+ @extra.create("UniversalTime")
+ end
+ @extra["UniversalTime"].mtime = aTime
+ @time = aTime
+ end
+
+ # Returns +true+ if the entry is a directory.
+ def directory?
+ raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
+ @ftype == :directory
+ end
+ alias :is_directory :directory?
+
+ # Returns +true+ if the entry is a file.
+ def file?
+ 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
+
+ def local_entry_offset #:nodoc:all
+ localHeaderOffset + local_header_size
+ end
+
+ def local_header_size #:nodoc:all
+ LOCAL_ENTRY_STATIC_HEADER_LENGTH + (@name ? @name.size : 0) + (@extra ? @extra.local_size : 0)
+ end
+
+ def cdir_header_size #:nodoc:all
+ CDIR_ENTRY_STATIC_HEADER_LENGTH + (@name ? @name.size : 0) +
+ (@extra ? @extra.c_dir_size : 0) + (@comment ? @comment.size : 0)
+ end
+
+ def next_header_offset #:nodoc:all
+ local_entry_offset + self.compressed_size
+ 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
+ @name
+ end
+
+ protected
+
+ def ZipEntry.read_zip_short(io) # :nodoc:
+ io.read(2).unpack('v')[0]
+ end
+
+ def ZipEntry.read_zip_long(io) # :nodoc:
+ io.read(4).unpack('V')[0]
+ end
+ public
+
+ LOCAL_ENTRY_SIGNATURE = 0x04034b50
+ LOCAL_ENTRY_STATIC_HEADER_LENGTH = 30
+ LOCAL_ENTRY_TRAILING_DESCRIPTOR_LENGTH = 4+4+4
+
+ def read_local_entry(io) #:nodoc:all
+ @localHeaderOffset = io.tell
+ staticSizedFieldsBuf = io.read(LOCAL_ENTRY_STATIC_HEADER_LENGTH)
+ unless (staticSizedFieldsBuf.size==LOCAL_ENTRY_STATIC_HEADER_LENGTH)
+ raise ZipError, "Premature end of file. Not enough data for zip entry local header"
+ end
+
+ @header_signature ,
+ @version ,
+ @fstype ,
+ @gp_flags ,
+ @compression_method,
+ lastModTime ,
+ lastModDate ,
+ @crc ,
+ @compressed_size ,
+ @size ,
+ nameLength ,
+ extraLength = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv')
+
+ unless (@header_signature == LOCAL_ENTRY_SIGNATURE)
+ raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
+ end
+ set_time(lastModDate, lastModTime)
+
+ @name = io.read(nameLength)
+ extra = io.read(extraLength)
+
+ if (extra && extra.length != extraLength)
+ raise ZipError, "Truncated local zip entry header"
+ else
+ if ZipExtraField === @extra
+ @extra.merge(extra)
+ else
+ @extra = ZipExtraField.new(extra)
+ end
+ end
+ end
+
+ def ZipEntry.read_local_entry(io)
+ entry = new(io.path)
+ entry.read_local_entry(io)
+ return entry
+ rescue ZipError
+ return nil
+ end
+
+ def write_local_entry(io) #:nodoc:all
+ @localHeaderOffset = io.tell
+
+ io <<
+ [LOCAL_ENTRY_SIGNATURE ,
+ 0 ,
+ 0 , # @gp_flags ,
+ @compression_method ,
+ @time.to_binary_dos_time , # @lastModTime ,
+ @time.to_binary_dos_date , # @lastModDate ,
+ @crc ,
+ @compressed_size ,
+ @size ,
+ @name ? @name.length : 0,
+ @extra? @extra.local_length : 0 ].pack('VvvvvvVVVvv')
+ io << @name
+ io << (@extra ? @extra.to_local_bin : "")
+ end
+
+ CENTRAL_DIRECTORY_ENTRY_SIGNATURE = 0x02014b50
+ CDIR_ENTRY_STATIC_HEADER_LENGTH = 46
+
+ def read_c_dir_entry(io) #:nodoc:all
+ staticSizedFieldsBuf = io.read(CDIR_ENTRY_STATIC_HEADER_LENGTH)
+ unless (staticSizedFieldsBuf.size == CDIR_ENTRY_STATIC_HEADER_LENGTH)
+ raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
+ end
+
+ @header_signature ,
+ @version , # version of encoding software
+ @fstype , # filesystem type
+ @versionNeededToExtract,
+ @gp_flags ,
+ @compression_method ,
+ lastModTime ,
+ lastModDate ,
+ @crc ,
+ @compressed_size ,
+ @size ,
+ nameLength ,
+ extraLength ,
+ commentLength ,
+ diskNumberStart ,
+ @internalFileAttributes,
+ @externalFileAttributes,
+ @localHeaderOffset ,
+ @name ,
+ @extra ,
+ @comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')
+
+ unless (@header_signature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
+ raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
+ end
+ set_time(lastModDate, lastModTime)
+
+ @name = io.read(nameLength)
+ if ZipExtraField === @extra
+ @extra.merge(io.read(extraLength))
+ else
+ @extra = ZipExtraField.new(io.read(extraLength))
+ end
+ @comment = io.read(commentLength)
+ unless (@comment && @comment.length == commentLength)
+ raise ZipError, "Truncated cdir zip entry header"
+ 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
+
+ def ZipEntry.read_c_dir_entry(io) #:nodoc:all
+ entry = new(io.path)
+ entry.read_c_dir_entry(io)
+ return entry
+ rescue ZipError
+ return nil
+ 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
+ case @fstype
+ when FSTYPE_UNIX
+ ft = nil