class Tar::FileReader

Constants

BOM_TREE

Attributes

header[R]

Public Class Methods

new(header, io, external_encoding: Encoding.default_external, internal_encoding: Encoding.default_internal, **encoding_options) click to toggle source
# File lib/tar/file_reader.rb, line 17
def initialize(header, io, external_encoding: Encoding.default_external, internal_encoding: Encoding.default_internal, **encoding_options)
  @header = header
  @io = io
  @closed = false
  @lineno = 0
  @pos = 0
  set_encoding external_encoding, internal_encoding, **encoding_options
end

Public Instance Methods

binmode() click to toggle source
# File lib/tar/file_reader.rb, line 123
def binmode
  set_encoding Encoding::BINARY
end
binmode?() click to toggle source
# File lib/tar/file_reader.rb, line 127
def binmode?
  check_not_closed!
  @external_encoding == Encoding::BINARY && @internal_encoding.nil?
end
bytes(&block) click to toggle source
# File lib/tar/file_reader.rb, line 176
def bytes(&block)
  warn "warning: #{self.class}#bytes is deprecated; use #each_byte instead"
  each_byte(&block)
end
chars(&block) click to toggle source
# File lib/tar/file_reader.rb, line 219
def chars(&block)
  warn "warning: #{self.class}#chars is deprecated; use #each_char instead"
  each_char(&block)
end
close() click to toggle source
# File lib/tar/file_reader.rb, line 26
def close
  @closed = true
end
closed?() click to toggle source
# File lib/tar/file_reader.rb, line 30
def closed?
  @closed || @io.closed?
end
codepoints(&block) click to toggle source
# File lib/tar/file_reader.rb, line 234
def codepoints(&block)
  warn "warning: #{self.class}#codepoints is deprecated; use #each_codepoint instead"
  each_codepoint(&block)
end
each(*args)
Alias for: each_line
each_byte() { |getbyte until eof?| ... } click to toggle source
# File lib/tar/file_reader.rb, line 170
def each_byte
  check_not_closed!
  return to_enum(__method__) unless block_given?
  yield getbyte until eof?
end
each_char() { |getc until eof?| ... } click to toggle source
# File lib/tar/file_reader.rb, line 213
def each_char
  check_not_closed!
  return to_enum(__method__) unless block_given?
  yield getc until eof?
end
each_codepoint() { |codepoint| ... } click to toggle source
# File lib/tar/file_reader.rb, line 224
def each_codepoint
  check_not_closed!
  return to_enum(__method__) unless block_given?
  each_char do |char|
    char.each_codepoint do |codepoint|
      yield codepoint
    end
  end
end
each_line(*args) { |read until eof?| ... } click to toggle source
# File lib/tar/file_reader.rb, line 253
def each_line(*args)
  line = Line.new(self, *args)
  check_not_closed!
  return to_enum(__method__, *args) unless block_given?
  yield line.read until eof?
end
Also aliased as: each
eof()
Alias for: eof?
eof?() click to toggle source
# File lib/tar/file_reader.rb, line 34
def eof?
  check_not_closed!
  @pos >= @header.size
end
Also aliased as: eof
external_encoding() click to toggle source
# File lib/tar/file_reader.rb, line 99
def external_encoding
  check_not_closed!
  @external_encoding
end
getbyte() click to toggle source
# File lib/tar/file_reader.rb, line 151
def getbyte
  check_not_closed!
  return nil if eof?
  @pos += 1
  @io.getbyte
end
getc() click to toggle source
# File lib/tar/file_reader.rb, line 181
def getc
  check_not_closed!
  return nil if eof?

  char = String.new(encoding: Encoding::BINARY)
  min_char_size, max_char_size = CharSize.minmax(external_encoding)

  until char.size == max_char_size || eof?
    char << read(min_char_size)

    char.force_encoding external_encoding
    return encode(char) if char.valid_encoding?
    char.force_encoding Encoding::BINARY
  end

  undo_getc_attempt char, min_char_size

  encode(char)
end
gets(*args) click to toggle source
# File lib/tar/file_reader.rb, line 239
def gets(*args)
  line = Line.new(self, *args)
  check_not_closed!
  return nil if eof?
  line.read
end
internal_encoding() click to toggle source
# File lib/tar/file_reader.rb, line 104
def internal_encoding
  check_not_closed!
  @internal_encoding
end
isatty()
Alias for: tty?
lineno() click to toggle source
# File lib/tar/file_reader.rb, line 55
def lineno
  check_not_closed!
  @lineno
end
lineno=(new_lineno) click to toggle source
# File lib/tar/file_reader.rb, line 60
def lineno=(new_lineno)
  check_not_closed!
  @lineno = new_lineno
end
lines(*args, &block) click to toggle source
# File lib/tar/file_reader.rb, line 261
def lines(*args, &block)
  warn "warning: #{self.class}#lines is deprecated; use #each_line instead"
  each_line(*args, &block)
end
pending() click to toggle source
# File lib/tar/file_reader.rb, line 50
def pending
  check_not_closed!
  [0, @header.size - @pos].max
end
pos() click to toggle source
# File lib/tar/file_reader.rb, line 40
def pos
  check_not_closed!
  @pos
end
Also aliased as: tell
pos=(new_pos) click to toggle source
# File lib/tar/file_reader.rb, line 46
def pos=(new_pos)
  seek new_pos
end
read(length = nil, buffer = nil) click to toggle source
# File lib/tar/file_reader.rb, line 65
def read(length = nil, buffer = nil)
  check_not_closed!

  data = @io.read(truncate(length), buffer)
  @pos += data.bytesize

  if length.nil?
    encode(data)
  else
    data.force_encoding(Encoding::BINARY)
  end
end
readbyte() click to toggle source
# File lib/tar/file_reader.rb, line 164
def readbyte
  check_not_closed!
  check_not_eof!
  getbyte
end
readchar() click to toggle source
# File lib/tar/file_reader.rb, line 207
def readchar
  check_not_closed!
  check_not_eof!
  getc
end
readline(*args) click to toggle source
# File lib/tar/file_reader.rb, line 246
def readline(*args)
  line = Line.new(self, *args)
  check_not_closed!
  check_not_eof!
  line.read
end
readlines(*args) click to toggle source
# File lib/tar/file_reader.rb, line 266
def readlines(*args)
  each_line(*args).to_a
end
readpartial(max_length, buffer = nil) click to toggle source
# File lib/tar/file_reader.rb, line 78
def readpartial(max_length, buffer = nil)
  check_not_closed!

  data = @io.readpartial(truncate(max_length), buffer)
  @pos += data.bytesize
  data.force_encoding(Encoding::BINARY)
end
rewind() click to toggle source
# File lib/tar/file_reader.rb, line 146
def rewind
  seek 0
  @lineno = 0
end
seek(amount, mode = IO::SEEK_SET) click to toggle source
# File lib/tar/file_reader.rb, line 138
def seek(amount, mode = IO::SEEK_SET)
  check_seekable!
  check_not_closed!
  offset = relativize(amount, mode)
  @io.seek offset, IO::SEEK_CUR
  @pos += offset
end
set_encoding(external_encoding, *internal_encoding, **encoding_options) click to toggle source
# File lib/tar/file_reader.rb, line 109
def set_encoding(external_encoding, *internal_encoding, **encoding_options)
  check_not_closed!

  external_encoding, internal_encoding = extract_encodings(external_encoding, *internal_encoding)

  if parse_bom?(external_encoding)
    external_encoding = parse_bom || external_encoding[4..-1]
  end

  @external_encoding = find_encoding(external_encoding, if_nil: Encoding.default_external, if_unsupported: Encoding.default_external)
  @internal_encoding = find_encoding(internal_encoding, if_nil: nil, if_unsupported: Encoding.default_internal)
  @encoding_options = encoding_options
end
skip_to_next_record() click to toggle source
# File lib/tar/file_reader.rb, line 86
def skip_to_next_record
  check_not_closed!

  target_pos = USTAR.records_size(@header.size)

  if seekable?
    seek target_pos
  else
    @io.read(target_pos - @pos)
    @pos = target_pos
  end
end
tell()
Alias for: pos
tty?() click to toggle source
# File lib/tar/file_reader.rb, line 132
def tty?
  check_not_closed!
  @io.respond_to?(:tty?) && @io.tty?
end
Also aliased as: isatty
ungetbyte(byte) click to toggle source
# File lib/tar/file_reader.rb, line 158
def ungetbyte(byte)
  check_not_closed!
  @pos -= 1
  @io.ungetbyte byte
end
ungetc(char) click to toggle source
# File lib/tar/file_reader.rb, line 201
def ungetc(char)
  char.encode(external_encoding).bytes.reverse_each do |byte|
    ungetbyte byte
  end
end

Private Instance Methods

check_not_closed!() click to toggle source
# File lib/tar/file_reader.rb, line 320
def check_not_closed!
  raise IOError, "closed stream" if closed?
end
check_not_eof!() click to toggle source
# File lib/tar/file_reader.rb, line 324
def check_not_eof!
  raise EOFError, "end of file reached" if eof?
end
check_seekable!() click to toggle source
# File lib/tar/file_reader.rb, line 338
def check_seekable!
  raise SeekNotSupported, "seek not supported by #{@io}" unless seekable?
end
encode(data) click to toggle source
# File lib/tar/file_reader.rb, line 299
def encode(data)
  data.force_encoding @external_encoding
  data.encode! @internal_encoding, @encoding_options if @internal_encoding
  data
end
extract_encodings(external_encoding, *internal_encoding) click to toggle source
# File lib/tar/file_reader.rb, line 276
def extract_encodings(external_encoding, *internal_encoding)
  raise ArgumentError, "wrong number of arguments (given #{internal_encoding.size + 1}, expected 1..2)" if internal_encoding.size > 1
  return [external_encoding, *internal_encoding] if external_encoding.nil? || external_encoding.is_a?(Encoding) || !internal_encoding.empty?
  external_encoding.split(":", 2)
end
find_encoding(encoding, if_nil:, if_unsupported:) click to toggle source
# File lib/tar/file_reader.rb, line 291
def find_encoding(encoding, if_nil:, if_unsupported:)
  return if_nil if encoding.nil? || encoding == ""
  Encoding.find(encoding)
rescue ArgumentError
  warn "warning: encoding #{encoding} unsupported, defaulting to #{if_unsupported}"
  if_unsupported
end
parse_bom() click to toggle source
# File lib/tar/file_reader.rb, line 286
def parse_bom
  return nil unless pos.zero?
  walk_bom_tree(BOM_TREE)
end
parse_bom?(encoding) click to toggle source
# File lib/tar/file_reader.rb, line 282
def parse_bom?(encoding)
  encoding.is_a?(String) && /^BOM\|/i.match?(encoding)
end
relativize(amount, mode) click to toggle source
# File lib/tar/file_reader.rb, line 305
def relativize(amount, mode)
  case mode
  when :CUR, IO::SEEK_CUR then amount
  when :SET, IO::SEEK_SET then amount - @pos
  when :END, IO::SEEK_END then @header.size + amount - @pos
  else raise ArgumentError, "unknown seek mode #{mode.inspect}, expected :CUR, :END, or :SET (or IO::SEEK_*)"
  end
end
seekable?() click to toggle source
# File lib/tar/file_reader.rb, line 328
def seekable?
  return @seekable if defined?(@seekable)
  @seekable = @io.respond_to?(:seek) && begin
    @io.pos
    true
  rescue Errno::ESPIPE
    false
  end
end
truncate(length) click to toggle source
# File lib/tar/file_reader.rb, line 272
def truncate(length)
  [pending, length].compact.min
end
undo_getc_attempt(char, min_char_size) click to toggle source
# File lib/tar/file_reader.rb, line 314
def undo_getc_attempt(char, min_char_size)
  char.slice!(min_char_size..-1).bytes.reverse_each do |byte|
    ungetbyte byte
  end
end
walk_bom_tree((tree, encoding)) click to toggle source
# File lib/tar/file_reader.rb, line 342
def walk_bom_tree((tree, encoding))
  byte = getbyte
  found_encoding = walk_bom_tree(tree[byte]) if tree.key?(byte)
  ungetbyte byte unless found_encoding
  found_encoding || encoding
end