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
312 def initialize(anIO)
313   @io     = anIO
314   @closed = false
315 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
297 def self.open(anIO)
298   writer = Writer.new(anIO)
299 
300   return writer unless block_given?
301 
302   begin
303     res = yield writer
304   ensure
305     writer.close
306   end
307 
308   res
309 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
372 def add_file(name, opts = {}) # :yields RestrictedStream, +opts+:
373   raise Archive::Tar::Minitar::BlockRequired unless block_given?
374   raise Archive::Tar::Minitar::ClosedStream if @closed
375   raise Archive::Tar::Minitar::NonSeekableStream unless @io.respond_to?(:pos=)
376 
377   name, prefix = split_name(name)
378   init_pos = @io.pos
379   @io.write("\0" * 512) # placeholder for the header
380 
381   yield RestrictedStream.new(@io), opts
382     # FIXME: what if an exception is raised in the block?
383 
384   size      = @io.pos - (init_pos + 512)
385   remainder = (512 - (size % 512)) % 512
386   @io.write("\0" * remainder)
387 
388   final_pos = @io.pos
389   @io.pos   = init_pos
390 
391   header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
392              :size => size, :gid => opts[:gid], :uid => opts[:uid],
393              :prefix => prefix }
394   header = Archive::Tar::PosixHeader.new(header).to_s
395   @io.write(header)
396   @io.pos = final_pos
397 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
331 def add_file_simple(name, opts = {}) # :yields BoundedStream:
332   raise Archive::Tar::Minitar::BlockRequired unless block_given?
333   raise Archive::Tar::ClosedStream if @closed
334 
335   name, prefix = split_name(name)
336 
337   header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
338     :size => opts[:size], :gid => opts[:gid], :uid => opts[:uid],
339     :prefix => prefix }
340   header = Archive::Tar::PosixHeader.new(header).to_s 
341   @io.write(header)
342 
343   os = BoundedStream.new(@io, opts[:size])
344   yield os
345     # FIXME: what if an exception is raised in the block?
346 
347   min_padding = opts[:size] - os.written
348   @io.write("\0" * min_padding)
349   remainder = (512 - (opts[:size] % 512)) % 512
350   @io.write("\0" * remainder)
351 end
close() click to toggle source

Closes the Writer.

    # File lib/archive/tar/minitar.rb
419 def close
420   return if @closed
421   @io.write("\0" * 1024)
422   @closed = true
423 end
flush() click to toggle source

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

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

Creates a directory in the tar.

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

Private Instance Methods

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