each_line(row_separator)
click to toggle source
def each_line(row_separator)
buffer = nil
input = @scanner.rest
position = @scanner.pos
offset = 0
n_row_separator_chars = row_separator.size
while true
input.each_line(row_separator) do |line|
@scanner.pos += line.bytesize
if buffer
if n_row_separator_chars == 2 and
buffer.end_with?(row_separator[0]) and
line.start_with?(row_separator[1])
buffer << line[0]
line = line[1..-1]
position += buffer.bytesize + offset
@scanner.pos = position
offset = 0
yield(buffer)
buffer = nil
next if line.empty?
else
buffer << line
line = buffer
buffer = nil
end
end
if line.end_with?(row_separator)
position += line.bytesize + offset
@scanner.pos = position
offset = 0
yield(line)
else
buffer = line
end
end
break unless read_chunk
input = @scanner.rest
position = @scanner.pos
offset = -buffer.bytesize if buffer
end
yield(buffer) if buffer
end
eos?()
click to toggle source
def eos?
@scanner.eos?
end
keep_back()
click to toggle source
def keep_back
start, buffer = @keeps.pop
if buffer
string = @scanner.string
keep = string.byteslice(start, string.bytesize - 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
read_chunk if @scanner.eos?
end
keep_drop()
click to toggle source
def keep_drop
@keeps.pop
end
keep_end()
click to toggle source
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
def keep_start
@keeps.push([@scanner.pos, nil])
end
rest()
click to toggle source
def rest
@scanner.rest
end
scan(pattern)
click to toggle source
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
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