Class: Archive::Tar::Minitar::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/archive/tar/minitar.rb

Overview

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

Defined Under Namespace

Classes: BoundedStream, RestrictedStream

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(anIO) ⇒ Writer

Creates and returns a new Writer object.



312
313
314
315
# File 'lib/archive/tar/minitar.rb', line 312

def initialize(anIO)
  @io     = anIO
  @closed = false
end

Class Method Details

.open(anIO) ⇒ Object

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.



297
298
299
300
301
302
303
304
305
306
307
308
309
# 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

Instance Method Details

#add_file(name, opts = {}) {|RestrictedStream.new(@io), opts| ... } ⇒ Object

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.

Yields:

Raises:



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# 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("\0" * 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("\0" * 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

#add_file_simple(name, opts = {}) {|os| ... } ⇒ Object

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.

Yields:

  • (os)

Raises:



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# 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("\0" * min_padding)
  remainder = (512 - (opts[:size] % 512)) % 512
  @io.write("\0" * remainder)
end

#closeObject

Closes the Writer.



419
420
421
422
423
# File 'lib/archive/tar/minitar.rb', line 419

def close
  return if @closed
  @io.write("\0" * 1024)
  @closed = true
end

#flushObject

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

Raises:



413
414
415
416
# File 'lib/archive/tar/minitar.rb', line 413

def flush
  raise ClosedStream if @closed
  @io.flush if @io.respond_to?(:flush)
end

#mkdir(name, opts = {}) ⇒ Object

Creates a directory in the tar.

Raises:



400
401
402
403
404
405
406
407
408
409
# 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