class Gem::Package::TarHeader
A header for a tar file
Constants
- FIELDS
Fields in the tar header
- PACK_FORMAT
Pack format for a tar header
- UNPACK_FORMAT
Unpack format for a tar header
Public Class Methods
from(stream)
click to toggle source
Creates a tar header from IO stream
# File rubygems/package/tar_header.rb, line 103 def self.from(stream) header = stream.read 512 return EMPTY if header == EMPTY_HEADER fields = header.unpack UNPACK_FORMAT new name: fields.shift, mode: strict_oct(fields.shift), uid: oct_or_256based(fields.shift), gid: oct_or_256based(fields.shift), size: strict_oct(fields.shift), mtime: strict_oct(fields.shift), checksum: strict_oct(fields.shift), typeflag: fields.shift, linkname: fields.shift, magic: fields.shift, version: strict_oct(fields.shift), uname: fields.shift, gname: fields.shift, devmajor: strict_oct(fields.shift), devminor: strict_oct(fields.shift), prefix: fields.shift, empty: false end
new(vals)
click to toggle source
Creates a new TarHeader
using vals
# File rubygems/package/tar_header.rb, line 149 def initialize(vals) unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] raise ArgumentError, ":name, :size, :prefix and :mode required" end @checksum = vals[:checksum] || "" @devmajor = vals[:devmajor] || 0 @devminor = vals[:devminor] || 0 @gid = vals[:gid] || 0 @gname = vals[:gname] || "wheel" @linkname = vals[:linkname] @magic = vals[:magic] || "ustar" @mode = vals[:mode] @mtime = vals[:mtime] || 0 @name = vals[:name] @prefix = vals[:prefix] @size = vals[:size] @typeflag = vals[:typeflag] @typeflag = "0" if @typeflag.nil? || @typeflag.empty? @uid = vals[:uid] || 0 @uname = vals[:uname] || "wheel" @version = vals[:version] || "00" @empty = vals[:empty] end
oct_or_256based(str)
click to toggle source
# File rubygems/package/tar_header.rb, line 136 def self.oct_or_256based(str) # \x80 flags a positive 256-based number # \ff flags a negative 256-based number # In case we have a match, parse it as a signed binary value # in big-endian order, except that the high-order bit is ignored. return str.unpack1("@4N") if /\A[\x80\xff]/n.match?(str) strict_oct(str) end
strict_oct(str)
click to toggle source
# File rubygems/package/tar_header.rb, line 129 def self.strict_oct(str) str.strip! return str.oct if /\A[0-7]*\z/.match?(str) raise ArgumentError, "#{str.inspect} is not an octal string" end
Public Instance Methods
empty?()
click to toggle source
Is the tar entry empty?
# File rubygems/package/tar_header.rb, line 194 def empty? @empty end
update_checksum()
click to toggle source
Updates the TarHeader’s checksum
# File rubygems/package/tar_header.rb, line 226 def update_checksum header = header " " * 8 @checksum = oct calculate_checksum(header), 6 end
Private Instance Methods
calculate_checksum(header)
click to toggle source
# File rubygems/package/tar_header.rb, line 233 def calculate_checksum(header) header.sum(0) end
header(checksum = @checksum)
click to toggle source
# File rubygems/package/tar_header.rb, line 237 def header(checksum = @checksum) header = [ name, oct(mode, 7), oct(uid, 7), oct(gid, 7), oct(size, 11), oct(mtime, 11), checksum, " ", typeflag, linkname, magic, oct(version, 2), uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix, ] header = header.pack PACK_FORMAT header.ljust 512, "\0" end
oct(num, len)
click to toggle source
# File rubygems/package/tar_header.rb, line 263 def oct(num, len) format("%0#{len}o", num) end