class Archive::Tar::Minitar::Writer

The class that writes a tar format archive to a data stream.

Public Class Methods

new(anIO) click to toggle source

Creates and returns a new Writer object.

    # File lib/archive/tar/minitar.rb
306 def initialize(anIO)
307   @io     = anIO
308   @closed = false
309 end
open(anIO) { |writer| ... } click to toggle source

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
291 def self.open(anIO)
292   writer = Writer.new(anIO)
293 
294   return writer unless block_given?
295 
296   begin
297     res = yield writer
298   ensure
299     writer.close
300   end
301 
302   res
303 end

Public Instance Methods

add_file(name, opts = {}) { |restricted_stream, opts| ... } click to toggle source

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
366 def add_file(name, opts = {}) # :yields RestrictedStream, +opts+:
367   raise Archive::Tar::Minitar::BlockRequired unless block_given?
368   raise Archive::Tar::Minitar::ClosedStream if @closed
369   raise Archive::Tar::Minitar::NonSeekableStream unless @io.respond_to?(:pos=)
370 
371   name, prefix = split_name(name)
372   init_pos = @io.pos
373   @io.write("\0" * 512) # placeholder for the header
374 
375   yield RestrictedStream.new(@io), opts
376     # FIXME: what if an exception is raised in the block?
377 
378   size      = @io.pos - (init_pos + 512)
379   remainder = (512 - (size % 512)) % 512
380   @io.write("\0" * remainder)
381 
382   final_pos = @io.pos
383   @io.pos   = init_pos
384 
385   header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
386              :size => size, :gid => opts[:gid], :uid => opts[:uid],
387              :prefix => prefix }
388   header = Archive::Tar::PosixHeader.new(header).to_s
389   @io.write(header)
390   @io.pos = final_pos
391 end
add_file_simple(name, opts = {}) { |os| ... } click to toggle source

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
325 def add_file_simple(name, opts = {}) # :yields BoundedStream:
326   raise Archive::Tar::Minitar::BlockRequired unless block_given?
327   raise Archive::Tar::ClosedStream if @closed
328 
329   name, prefix = split_name(name)
330 
331   header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
332     :size => opts[:size], :gid => opts[:gid], :uid => opts[:uid],
333     :prefix => prefix }
334   header = Archive::Tar::PosixHeader.new(header).to_s 
335   @io.write(header)
336 
337   os = BoundedStream.new(@io, opts[:size])
338   yield os
339     # FIXME: what if an exception is raised in the block?
340 
341   min_padding = opts[:size] - os.written
342   @io.write("\0" * min_padding)
343   remainder = (512 - (opts[:size] % 512)) % 512
344   @io.write("\0" * remainder)
345 end
close() click to toggle source

Closes the Writer.

    # File lib/archive/tar/minitar.rb
413 def close
414   return if @closed
415   @io.write("\0" * 1024)
416   @closed = true
417 end
flush() click to toggle source

Passes the flush method to the wrapped stream, used for buffered streams.

    # File lib/archive/tar/minitar.rb
407 def flush
408   raise ClosedStream if @closed
409   @io.flush if @io.respond_to?(:flush)
410 end
mkdir(name, opts = {}) click to toggle source

Creates a directory in the tar.

    # File lib/archive/tar/minitar.rb
394 def mkdir(name, opts = {})
395   raise ClosedStream if @closed
396   name, prefix = split_name(name)
397   header = { :name => name, :mode => opts[:mode], :typeflag => "5",
398              :size => 0, :gid => opts[:gid], :uid => opts[:uid],
399              :mtime => opts[:mtime], :prefix => prefix }
400   header = Archive::Tar::PosixHeader.new(header).to_s
401   @io.write(header)
402   nil
403 end

Private Instance Methods

split_name(name) click to toggle source
    # File lib/archive/tar/minitar.rb
420 def split_name(name)
421   raise FileNameTooLong if name.size > 256
422   if name.size <= 100
423     prefix = ""
424   else
425     parts = name.split(/\//)
426     newname = parts.pop
427 
428     nxt = ""
429 
430     loop do
431       nxt = parts.pop
432       break if newname.size + 1 + nxt.size > 100
433       newname = "#{nxt}/#{newname}"
434     end
435 
436     prefix = (parts + [nxt]).join("/")
437 
438     name = newname
439 
440     raise FileNameTooLong if name.size > 100 || prefix.size > 155
441   end
442   return name, prefix
443 end