class Archive::Tar::Minitar::Writer
The class that writes a tar format archive to a data stream.
Public Class Methods
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
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
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
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
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
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
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
# 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