class CSV::Parser::InputsScanner

Public Class Methods

new(inputs, encoding, chunk_size: 8192) click to toggle source
# File lib/csv/parser.rb, line 43
def initialize(inputs, encoding, chunk_size: 8192)
  @inputs = inputs.dup
  @encoding = encoding
  @chunk_size = chunk_size
  @last_scanner = @inputs.empty?
  @keeps = []
  read_chunk
end

Public Instance Methods

eos?() click to toggle source
# File lib/csv/parser.rb, line 75
def eos?
  @scanner.eos?
end
keep_back() click to toggle source
# File lib/csv/parser.rb, line 93
def keep_back
  start, buffer = @keeps.pop
  if buffer
    string = @scanner.string
    keep = string[start, string.size - start]
    if keep and not keep.empty?
      @inputs.unshift(StringIO.new(keep))
      @last_scanner = false
    end
    @scanner = StringScanner.new(buffer)
  else
    @scanner.pos = start
  end
end
keep_drop() click to toggle source
# File lib/csv/parser.rb, line 108
def keep_drop
  @keeps.pop
end
keep_end() click to toggle source
# File lib/csv/parser.rb, line 83
def keep_end
  start, buffer = @keeps.pop
  keep = @scanner.string[start, @scanner.pos - start]
  if buffer
    buffer << keep
    keep = buffer
  end
  keep
end
keep_start() click to toggle source
# File lib/csv/parser.rb, line 79
def keep_start
  @keeps.push([@scanner.pos, nil])
end
rest() click to toggle source
# File lib/csv/parser.rb, line 112
def rest
  @scanner.rest
end
scan(pattern) click to toggle source
# File lib/csv/parser.rb, line 52
def scan(pattern)
  value = @scanner.scan(pattern)
  return value if @last_scanner

  if value
    read_chunk if @scanner.eos?
    return value
  else
    nil
  end
end
scan_all(pattern) click to toggle source
# File lib/csv/parser.rb, line 64
def scan_all(pattern)
  value = @scanner.scan(pattern)
  return value if @last_scanner

  return nil if value.nil?
  while @scanner.eos? and read_chunk and (sub_value = @scanner.scan(pattern))
    value << sub_value
  end
  value
end

Private Instance Methods

read_chunk() click to toggle source
# File lib/csv/parser.rb, line 117
def read_chunk
  return false if @last_scanner

  unless @keeps.empty?
    keep = @keeps.last
    keep_start = keep[0]
    string = @scanner.string
    keep_data = string[keep_start, @scanner.pos - keep_start]
    if keep_data
      keep_buffer = keep[1]
      if keep_buffer
        keep_buffer << keep_data
      else
        keep[1] = keep_data.dup
      end
    end
    keep[0] = 0
  end

  input = @inputs.first
  case input
  when StringIO
    string = input.string
    raise InvalidEncoding unless string.valid_encoding?
    @scanner = StringScanner.new(string)
    @inputs.shift
    @last_scanner = @inputs.empty?
    true
  else
    chunk = input.gets(nil, @chunk_size)
    if chunk
      raise InvalidEncoding unless chunk.valid_encoding?
      @scanner = StringScanner.new(chunk)
      if input.respond_to?(:eof?) and input.eof?
        @inputs.shift
        @last_scanner = @inputs.empty?
      end
      true
    else
      @scanner = StringScanner.new("".encode(@encoding))
      @inputs.shift
      @last_scanner = @inputs.empty?
      if @last_scanner
        false
      else
        read_chunk
      end
    end
  end
end