Class: Zippo::ZipFileWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/zippo/zip_file_writer.rb

Overview

ZipFileWriter writes the contents of a ZipDirectory to a Zip file.

Instance Method Summary collapse

Constructor Details

#initialize(directory, filename) ⇒ ZipFileWriter

Returns a new instance of ZipFileWriter.

Parameters:

  • directory (ZipDirectory)

    the ZipDirectory to write

  • filename (String)

    the filename to write to



6
7
8
9
# File 'lib/zippo/zip_file_writer.rb', line 6

def initialize(directory, filename)
  @directory = directory
  @filename = filename
end

Instance Method Details

#writeObject

Writes the directory to the file.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/zippo/zip_file_writer.rb', line 12

def write
  File.open(@filename, 'wb:ASCII-8BIT') do |io|
    packer = LocalFileHeader::Packer.new io
    headers = []
    @directory.each do |member|
      header = CdFileHeader.default
      header.compression_method = 8 # XXX configurable
      # XXX hack fix for maintaining method in zipped data copies
      if member.is_a? ZipMember
        header.compression_method = member.compression_method
      end
      header.name = member.name
      header.extra_field = "" # XXX extra field unimplemented
      header_size = header.file_name_length + header.extra_field_length + 30

      # record header position so we can write it later
      header.local_file_header_offset = io.pos

      # move to after the header
      io.seek header_size, IO::SEEK_CUR

      # write the compressed data
      header.compressed_size, header.uncompressed_size, header.crc32 =
        member.write_to io, header.compression_method

      # write the completed header, returning to the current position
      io.seek header.local_file_header_offset
      # packer.pack LocalFileHeader.from header.convert_to LocalHileHeader
      packer.pack header.convert_to LocalFileHeader
      io.seek header.compressed_size, IO::SEEK_CUR
      headers << header
    end

    eocdr = EndCdRecord.default
    eocdr.cd_offset = io.pos
    packer = CdFileHeader::Packer.new io
    headers.each do |header|
      packer.pack header
    end
    eocdr.cd_size = io.pos - eocdr.cd_offset
    eocdr.records = eocdr.total_records = headers.size
    EndCdRecord::Packer.new(io).pack eocdr
  end
end