diff --git a/NEWS b/NEWS index 5d0d946..f6fa9a0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ += Version 0.4.0 = + +ZipFile is now mutable and provides a more convenient way of modifying +zip archives than ZipOutputStream. + +Runs without warnings with -w switch. + = Version 0.3.1 = Rudimentary support for writing zip archives. diff --git a/TODO b/TODO index 0400849..db482dc 100644 --- a/TODO +++ b/TODO @@ -3,9 +3,24 @@ write ZipFile. unit test writeFile (onExistsProc) unit test rename onExistsProc unit test yield on ZipFile::getInputStream +unit test adding directories (and implement) +unit test adding directories recursively (and implement) +unit test ZipFile.checkIntegrity method (and implement) +unit test and implement recursive extract (and implement) + +performance improve method +ZipStreamableZipEntry.writeToZipOutputStream by not +decompressing/compressing the data. release 0.4.0 +implement small gui app on top, to exercise library and to discover +what features should be added to rubyzip. Use tk. + +implement setting the date correctly in ZipEntry with now as default + +release 0.4.1 with small gui demo app and fixes + Refactor ZipFileTest to reduce duplicated code, divide into different test classes if different fixtures are required and use setup/teardown some more. diff --git a/zip.rb b/zip.rb index 9ff09c8..a253cc7 100755 --- a/zip.rb +++ b/zip.rb @@ -33,7 +33,7 @@ module Zip end def gets(aSepString=$/) - @outputBuffer="" unless @outputBuffer + @outputBuffer ||= "" return read if aSepString == nil aSepString="#{$/}#{$/}" if aSepString == "" @@ -50,6 +50,7 @@ module Zip end def flush + @outputBuffer ||= "" retVal=@outputBuffer @outputBuffer="" return retVal @@ -117,6 +118,7 @@ module Zip @archiveIO = File.open(filename, "rb") @archiveIO.seek(offset, IO::SEEK_SET) @decompressor = NullDecompressor.instance + @currentEntry = nil end def close @@ -177,6 +179,7 @@ module Zip super @zlibInflater = Zlib::Inflate.new(-Zlib::Inflate::MAX_WBITS) @outputBuffer="" + @hasReturnedEmptyString = false end def read(numberOfBytes = nil) @@ -265,6 +268,7 @@ module Zip def initialize(name = "", comment = "", extra = "", compressedSize = 0, crc = 0, compressionMethod = ZipEntry::DEFLATED, size = 0) + @localHeaderOffset = 0 @comment, @compressedSize, @crc, @extra, @compressionMethod, @name, @size, @isDirectory = comment, compressedSize, crc, extra, compressionMethod, name, size @@ -352,11 +356,11 @@ module Zip io << [LOCAL_ENTRY_SIGNATURE , - @version , - @gpFlags , + 0 , # @version , + 0 , # @gpFlags , @compressionMethod , - @lastModTime , - @lastModDate , + 0 , # @lastModTime , + 0 , # @lastModDate , @crc , @compressedSize , @size , @@ -420,12 +424,12 @@ module Zip def writeCDirEntry(io) io << [CENTRAL_DIRECTORY_ENTRY_SIGNATURE, - @version , - @versionNeededToExtract , - @gpFlags , + 0 , # @version , + 0 , # @versionNeededToExtract , + 0 , # @gpFlags , @compressionMethod , - @lastModTime , - @lastModDate , + 0 , # @lastModTime , + 0 , # @lastModDate , @crc , @compressedSize , @size , @@ -433,8 +437,8 @@ module Zip @extra ? @extra.length : 0 , @comment ? comment.length : 0 , 0 , # disk number start - @internalFileAttributes , - @externalFileAttributes , + 0 , # @internalFileAttributes , + 0 , # @externalFileAttributes , @localHeaderOffset , @name , @extra , @@ -483,6 +487,9 @@ module Zip @outputStream = File.new(@fileName, "wb") @entries = [] @compressor = NullCompressor.instance + @closed = false + @currentEntry = nil + @comment = nil end def ZipOutputStream.open(fileName) @@ -707,7 +714,7 @@ module Zip end def each(&proc) - @entries.each &proc + @entries.each(&proc) end def ZipCentralDirectory.readFromStream(io) @@ -734,6 +741,7 @@ module Zip def initialize(name) @name=name + @comment = "" File.open(name) { |file| readFromStream(file) @@ -742,7 +750,7 @@ module Zip def BasicZipFile.foreach(aZipFileName, &block) zipFile = BasicZipFile.new(aZipFileName) - zipFile.each &block + zipFile.each(&block) end def getInputStream(entry) @@ -772,6 +780,7 @@ module Zip def initialize(fileName, create = nil) @name = fileName + @comment = "" if (File.exists?(fileName)) super(fileName) fixEntries @@ -825,7 +834,7 @@ module Zip end def getInputStream(entry, &aProc) - getEntry(entry).getInputStream &aProc + getEntry(entry).getInputStream(&aProc) end def extract(entry, destPath, onExistsProc = proc { false }) diff --git a/ziptest.rb b/ziptest.rb index efdb983..ef9dbfe 100755 --- a/ziptest.rb +++ b/ziptest.rb @@ -6,7 +6,6 @@ require 'zip' include Zip - class AbstractInputStreamTest < RUNIT::TestCase # AbstractInputStream subclass that provides a read method @@ -141,7 +140,7 @@ module IOizeString attr_reader :tell def read(count = nil) - @tell = 0 unless @tell + @tell ||= 0 count = size unless count retVal = slice(@tell, count) @tell += count @@ -149,6 +148,7 @@ module IOizeString end def seek(index, offset) + @tell ||= 0 case offset when IO::SEEK_END newPos = size + index @@ -165,6 +165,10 @@ module IOizeString @tell=newPos end end + + def reset + @tell = 0 + end end class ZipLocalEntryTest < RUNIT::TestCase @@ -197,7 +201,7 @@ class ZipLocalEntryTest < RUNIT::TestCase def test_readLocalEntryFromTruncatedZipFile zipFragment="" File.open(TestZipFile::TEST_ZIP2.zipName) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes - zipFragment.extend(IOizeString) + zipFragment.extend(IOizeString).reset entry = ZipEntry.new entry.readLocalEntry(zipFragment) fail "ZipError expected" @@ -751,7 +755,7 @@ class ZipOutputStreamTest < RUNIT::TestCase begin zos = ZipOutputStream.open(name) rescue Exception - assert ($!.kind_of?(Errno::EISDIR) || $!.kind_of?(Errno::EEXIST), + assert($!.kind_of?(Errno::EISDIR) || $!.kind_of?(Errno::EEXIST), "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!}") end end @@ -781,7 +785,7 @@ module Enumerable index=0 each_with_index { |element, index| - return false unless yield (element, otherAsArray[index]) + return false unless yield(element, otherAsArray[index]) } return index+1 == otherAsArray.size end @@ -1051,14 +1055,14 @@ class ZipFileTest < RUNIT::TestCase File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName) zf = ZipFile.new(TEST_ZIP.zipName) - assert(zf.entries.map { |e| e.name }.include? (entryToRemove)) + assert(zf.entries.map { |e| e.name }.include?(entryToRemove)) zf.remove(entryToRemove) - assert(! zf.entries.map { |e| e.name }.include? (entryToRemove)) + assert(! zf.entries.map { |e| e.name }.include?(entryToRemove)) assert_equals(zf.entries.map {|x| x.name }.sort, remainingEntries.sort) zf.close zfRead = ZipFile.new(TEST_ZIP.zipName) - assert(! zfRead.entries.map { |e| e.name }.include? (entryToRemove)) + assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove)) assert_equals(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort) zfRead.close end @@ -1080,12 +1084,12 @@ class ZipFileTest < RUNIT::TestCase def test_extractNonEntry zf = ZipFile.new(TEST_ZIP.zipName) - assert_exception(ZipError) { zf.extract("nonExistingEntry") } + assert_exception(ZipError) { zf.extract("nonExistingEntry", "nonExistingEntry") } ensure zf.close if zf end - def test_extractNonEntry + def test_extractNonEntry2 outFile = "outfile" assert_exception(ZipError) { zf = ZipFile.new(TEST_ZIP.zipName) @@ -1286,7 +1290,6 @@ end TestZipFile::createTestZips(ARGV.index("recreate") != nil) TestFiles::createTestFiles(ARGV.index("recreate") != nil) - # Copyright (C) 2002 Thomas Sondergaard # rubyzip is free software; you can redistribute it and/or # modify it under the terms of the ruby license.