class Zip::OutputStream
def <<(data)
def <<(data) @compressor << data self end
def close
def close return if @closed finalize_current_entry update_local_headers write_central_directory @output_stream.close @closed = true end
def close_buffer
def close_buffer return @output_stream if @closed finalize_current_entry update_local_headers write_central_directory @closed = true @output_stream end
def copy_raw_entry(entry)
def copy_raw_entry(entry) entry = entry.dup raise Error, 'zip stream is closed' if @closed raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry) finalize_current_entry @entry_set << entry src_pos = entry.local_header_offset entry.write_local_entry(@output_stream) @compressor = NullCompressor.instance entry.get_raw_input_stream do |is| is.seek(src_pos, IO::SEEK_SET) ::Zip::Entry.read_local_entry(is) IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size) end @compressor = NullCompressor.instance @current_entry = nil end
def finalize_current_entry
def finalize_current_entry return unless @current_entry finish @current_entry.compressed_size = @output_stream.tell - \ @current_entry.local_header_offset - \ @current_entry.calculate_local_header_size @current_entry.size = @compressor.size @current_entry.crc = @compressor.crc @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size) @current_entry.gp_flags |= @encrypter.gp_flags @current_entry = nil @compressor = ::Zip::NullCompressor.instance end
def finish
def finish @compressor.finish end
def get_compressor(entry, level)
def get_compressor(entry, level) case entry.compression_method when Entry::DEFLATED ::Zip::Deflater.new(@output_stream, level, @encrypter) when Entry::STORED ::Zip::PassThruCompressor.new(@output_stream) else raise ::Zip::CompressionMethodError, "Invalid compression method: '#{entry.compression_method}'" end end
def init_next_entry(entry, level = Zip.default_compression)
def init_next_entry(entry, level = Zip.default_compression) finalize_current_entry @entry_set << entry entry.write_local_entry(@output_stream) @encrypter.reset! @output_stream << @encrypter.header(entry.mtime) @compressor = get_compressor(entry, level) end
def initialize(file_name, dep_stream = false, dep_encrypter = nil, stream: false, encrypter: nil)
Opens the indicated zip file. If a file with that name already
def initialize(file_name, dep_stream = false, dep_encrypter = nil, stream: false, encrypter: nil) super() Zip.warn_about_v3_api('Zip::OutputStream.new') if dep_stream || !dep_encrypter.nil? @file_name = file_name @output_stream = if stream || dep_stream iostream = @file_name.dup iostream.reopen(@file_name) iostream.rewind iostream else ::File.new(@file_name, 'wb') end @entry_set = ::Zip::EntrySet.new @compressor = ::Zip::NullCompressor.instance @encrypter = encrypter || dep_encrypter || ::Zip::NullEncrypter.new @closed = false @current_entry = nil @comment = nil end
def open(file_name, dep_encrypter = nil, encrypter: nil)
def open(file_name, dep_encrypter = nil, encrypter: nil) return new(file_name) unless block_given? Zip.warn_about_v3_api('Zip::OutputStream.open') unless dep_encrypter.nil? zos = new(file_name, stream: false, encrypter: (encrypter || dep_encrypter)) yield zos ensure zos.close if zos end
def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
Closes the current entry and opens a new for writing.
def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression) raise Error, 'zip stream is closed' if @closed new_entry = if entry_name.kind_of?(Entry) entry_name else Entry.new(@file_name, entry_name.to_s) end new_entry.comment = comment unless comment.nil? unless extra.nil? new_entry.extra = extra.kind_of?(ExtraField) ? extra : ExtraField.new(extra.to_s) end new_entry.compression_method = compression_method unless compression_method.nil? init_next_entry(new_entry, level) @current_entry = new_entry end
def update_local_headers
def update_local_headers pos = @output_stream.pos @entry_set.each do |entry| @output_stream.pos = entry.local_header_offset entry.write_local_entry(@output_stream, true) end @output_stream.pos = pos end
def write_buffer(io = ::StringIO.new, dep_encrypter = nil, encrypter: nil)
def write_buffer(io = ::StringIO.new, dep_encrypter = nil, encrypter: nil) Zip.warn_about_v3_api('Zip::OutputStream.write_buffer') unless dep_encrypter.nil? io.binmode if io.respond_to?(:binmode) zos = new(io, stream: true, encrypter: (encrypter || dep_encrypter)) yield zos zos.close_buffer end
def write_central_directory
def write_central_directory cdir = CentralDirectory.new(@entry_set, @comment) cdir.write_to_stream(@output_stream) end