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 306 def initialize(anIO) 307 @io = anIO 308 @closed = false 309 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 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
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
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
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
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
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
# 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