The class that writes a tar format archive to a data stream.
Creates and returns a new Writer object.
# File lib/archive/tar/minitar.rb, line 312 def initialize(anIO) @io = anIO @closed = false end
With no associated block, +Writer::open+ is a synonym for +Writer::new+. If the optional code block is given, it will be passed the new writer as an argument and the Writer object will automatically be closed when the block terminates. In this instance, +Writer::open+ returns the value of the block.
# File lib/archive/tar/minitar.rb, line 297 def self.open(anIO) writer = Writer.new(anIO) return writer unless block_given? begin res = yield writer ensure writer.close end res end
Adds a file to the archive as name
. opts
must
contain the following value:
:mode
The Unix file permissions mode value.
opts
may contain the following values:
:uid
: The Unix file owner user ID number.
:gid
: The Unix file owner group ID number.
:mtime
The integer modification time value.
The file's size will be determined from the amount of data written to the stream.
For add_file to be used, the Archive::Tar::Minitar::Writer must be wrapping a stream object that is seekable (e.g., it responds to pos=). Otherwise, add_file_simple must be used.
opts
may be modified during the writing to the stream.
# File lib/archive/tar/minitar.rb, line 372 def add_file(name, opts = {}) # :yields RestrictedStream, +opts+: raise Archive::Tar::Minitar::BlockRequired unless block_given? raise Archive::Tar::Minitar::ClosedStream if @closed raise Archive::Tar::Minitar::NonSeekableStream unless @io.respond_to?(:pos=) name, prefix = split_name(name) init_pos = @io.pos @io.write("\00"" * 512) # placeholder for the header yield RestrictedStream.new(@io), opts # FIXME: what if an exception is raised in the block? size = @io.pos - (init_pos + 512) remainder = (512 - (size % 512)) % 512 @io.write("\00"" * remainder) final_pos = @io.pos @io.pos = init_pos header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime], :size => size, :gid => opts[:gid], :uid => opts[:uid], :prefix => prefix } header = Archive::Tar::PosixHeader.new(header).to_s @io.write(header) @io.pos = final_pos end
Adds a file to the archive as name
. opts
must
contain the following values:
:mode
The Unix file permissions mode value.
:size
The size, in bytes.
opts
may contain the following values:
:uid
: The Unix file owner user ID number.
:gid
: The Unix file owner group ID number.
:mtime
The integer modification time value.
It will not be possible to add more than opts[:size]
bytes to
the file.
# File lib/archive/tar/minitar.rb, line 331 def add_file_simple(name, opts = {}) # :yields BoundedStream: raise Archive::Tar::Minitar::BlockRequired unless block_given? raise Archive::Tar::ClosedStream if @closed name, prefix = split_name(name) header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime], :size => opts[:size], :gid => opts[:gid], :uid => opts[:uid], :prefix => prefix } header = Archive::Tar::PosixHeader.new(header).to_s @io.write(header) os = BoundedStream.new(@io, opts[:size]) yield os # FIXME: what if an exception is raised in the block? min_padding = opts[:size] - os.written @io.write("\00"" * min_padding) remainder = (512 - (opts[:size] % 512)) % 512 @io.write("\00"" * remainder) end
Closes the Writer.
# File lib/archive/tar/minitar.rb, line 419 def close return if @closed @io.write("\00"" * 1024) @closed = true end
Passes the flush method to the wrapped stream, used for buffered streams.
# File lib/archive/tar/minitar.rb, line 413 def flush raise ClosedStream if @closed @io.flush if @io.respond_to?(:flush) end
Creates a directory in the tar.
# File lib/archive/tar/minitar.rb, line 400 def mkdir(name, opts = {}) raise ClosedStream if @closed name, prefix = split_name(name) header = { :name => name, :mode => opts[:mode], :typeflag => "5", :size => 0, :gid => opts[:gid], :uid => opts[:uid], :mtime => opts[:mtime], :prefix => prefix } header = Archive::Tar::PosixHeader.new(header).to_s @io.write(header) nil end
# File lib/archive/tar/minitar.rb, line 426 def split_name(name) raise FileNameTooLong if name.size > 256 if name.size <= 100 prefix = "" else parts = name.split(/\//) newname = parts.pop nxt = "" loop do nxt = parts.pop break if newname.size + 1 + nxt.size > 100 newname = "#{nxt}/#{newname}" end prefix = (parts + [nxt]).join("/") name = newname raise FileNameTooLong if name.size > 100 || prefix.size > 155 end return name, prefix end