Zip write support is now fully functional in the form of ZipOutputStream.

This commit is contained in:
thomas 2002-01-25 21:51:28 +00:00
parent 559c8032ea
commit c6f5747df7
4 changed files with 71 additions and 15 deletions

4
NEWS
View File

@ -1,3 +1,7 @@
= Version 0.3.0 =
Rudimentary support for writing zip archives.
= Version 0.2.2 = = Version 0.2.2 =
Fixed and extended unit test suite. Updated to work with ruby/zlib Fixed and extended unit test suite. Updated to work with ruby/zlib

View File

@ -18,6 +18,9 @@ ruby-zlib: http://www.blue.sky.or.jp/atelier/#ruby-zlib
This library requires ruby/zlib version 0.5.0 or newer. This library requires ruby/zlib version 0.5.0 or newer.
As of this writing ruby/zlib 0.5.0 is only available as
ruby-zlib-0.5.0-pre3 at http://www.blue.sky.or.jp/atelier/ruby/
= LICENSE = = LICENSE =

25
zip.rb
View File

@ -453,7 +453,7 @@ module Zip
@fileName = fileName @fileName = fileName
@outputStream = File.new(@fileName, "wb") @outputStream = File.new(@fileName, "wb")
@entries = [] @entries = []
@compressor = NullCompressor @compressor = NullCompressor.instance
end end
def ZipOutputStream.open(fileName) def ZipOutputStream.open(fileName)
@ -483,10 +483,12 @@ module Zip
def finalizeCurrentEntry def finalizeCurrentEntry
return unless @currentEntry return unless @currentEntry
finish finish
@currentEntry.compressedSize = @outputStream.tell - @currentEntry.localHeaderOffset - @currentEntry.localHeaderSize @currentEntry.compressedSize = @outputStream.tell - @currentEntry.localHeaderOffset -
@currentEntry.localHeaderSize
@currentEntry.size = @compressor.size @currentEntry.size = @compressor.size
@currentEntry.crc = @compressor.crc
@currentEntry = nil @currentEntry = nil
@compressor = NullCompressor @compressor = NullCompressor.instance
end end
def initNextEntry(entry, level = Zlib::DEFAULT_COMPRESSION) def initNextEntry(entry, level = Zlib::DEFAULT_COMPRESSION)
@ -520,13 +522,15 @@ module Zip
end end
protected protected
def << (data)
@compressor << data
end
def finish def finish
@compressor.finish @compressor.finish
end end
public
def << (data)
@compressor << data
end
end end
@ -538,22 +542,25 @@ module Zip
class PassThruCompressor < Compressor class PassThruCompressor < Compressor
def initialize(outputStream) def initialize(outputStream)
@outputStream = outputStream @outputStream = outputStream
@crc = Zlib::crc32
@size = 0 @size = 0
end end
def << (data) def << (data)
val = data.to_s val = data.to_s
@crc = Zlib::crc32(val, @crc)
@size += val.size @size += val.size
@outputStream << val @outputStream << val
end end
attr_reader :size attr_reader :size, :crc
end end
class NullCompressor < Compressor class NullCompressor < Compressor
include Singleton include Singleton
def << (data) def << (data)
raise IOError, "closed stream"
end end
attr_reader :size, :compressedSize attr_reader :size, :compressedSize
@ -564,10 +571,12 @@ module Zip
@outputStream = outputStream @outputStream = outputStream
@zlibDeflater = Zlib::Deflate.new(level, -Zlib::Deflate::MAX_WBITS) @zlibDeflater = Zlib::Deflate.new(level, -Zlib::Deflate::MAX_WBITS)
@size = 0 @size = 0
@crc = Zlib::crc32
end end
def << (data) def << (data)
val = data.to_s val = data.to_s
@crc = Zlib::crc32(val, @crc)
@size += val.size @size += val.size
@outputStream << @zlibDeflater.deflate(data) @outputStream << @zlibDeflater.deflate(data)
end end
@ -578,7 +587,7 @@ module Zip
end end
end end
attr_reader :size attr_reader :size, :crc
end end
class ZipCentralDirectory class ZipCentralDirectory

View File

@ -551,7 +551,23 @@ class AbstractOutputStreamTest < RUNIT::TestCase
end end
end end
module CrcTest
def runCrcTest(compressorClass)
str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
fakeOut = AbstractOutputStreamTest::TestOutputStream.new
deflater = compressorClass.new(fakeOut)
deflater << str
assert_equals(0x919920fc, deflater.crc)
end
end
class PassThruCompressorTest < RUNIT::TestCase class PassThruCompressorTest < RUNIT::TestCase
include CrcTest
def test_size def test_size
File.open("dummy.txt", "wb") { File.open("dummy.txt", "wb") {
|file| |file|
@ -573,9 +589,15 @@ class PassThruCompressorTest < RUNIT::TestCase
assert_equals(compressor.size, t1.size + t2.size + t3.size) assert_equals(compressor.size, t1.size + t2.size + t3.size)
} }
end end
def test_crc
runCrcTest(PassThruCompressor)
end
end end
class DeflaterTest < RUNIT::TestCase class DeflaterTest < RUNIT::TestCase
include CrcTest
def test_outputOperator def test_outputOperator
txt = loadFile("ziptest.rb") txt = loadFile("ziptest.rb")
deflate(txt, "deflatertest.bin") deflate(txt, "deflatertest.bin")
@ -608,8 +630,11 @@ class DeflaterTest < RUNIT::TestCase
txt = inflater.read txt = inflater.read
} }
end end
end
def test_crc
runCrcTest(Deflater)
end
end
class ZipOutputStreamTest < RUNIT::TestCase class ZipOutputStreamTest < RUNIT::TestCase
include AssertEntry include AssertEntry
@ -634,18 +659,33 @@ class ZipOutputStreamTest < RUNIT::TestCase
assertTestZipContents(TEST_ZIP) assertTestZipContents(TEST_ZIP)
end end
def test_putOnClosedStream
fail "implement and expect ZipError"
end
def test_writingToClosedStream def test_writingToClosedStream
fail "implement this test and make sure behaviour is similar to closed File object" assertIOErrorInClosedStream { |zos| zos << "hello world" }
assertIOErrorInClosedStream { |zos| zos.puts "hello world" }
assertIOErrorInClosedStream { |zos| zos.write "hello world" }
end end
def test_cannotOpenFile def test_cannotOpenFile
fail "implement and expect zip.closed? and exception from constructor" name = "emptytestdir"
ensureDir(name)
assert_exception(Errno::EISDIR, "Is a directorYY") {
zos = ZipOutputStream.open(name)
}
end end
def ensureDir(name)
return if File.stat(name).directory?
File.delete(name)
Dir.mkdir(name)
end
def assertIOErrorInClosedStream
assert_exception(IOError) {
zos = ZipOutputStream.new("test_putOnClosedStream.zip")
zos.close
yield zos
}
end
def writeTestZip(zos) def writeTestZip(zos)
TEST_ZIP.entryNames.each { TEST_ZIP.entryNames.each {