method
parse_body
v1_8_7_72 -
Show latest stable
- Class:
CSV
parse_body(src, idx, fs, rs)private
No documentation available.
# File lib/csv.rb, line 343
def parse_body(src, idx, fs, rs)
fs_str = fs
fs_size = fs_str.size
rs_str = rs || "\n"
rs_size = rs_str.size
fs_idx = rs_idx = 0
cell = Cell.new
state = :ST_START
quoted = cr = false
c = nil
last_idx = idx
while c = src[idx]
unless quoted
fschar = (c == fs_str[fs_idx])
rschar = (c == rs_str[rs_idx])
# simple 1 char backtrack
if !fschar and c == fs_str[0]
fs_idx = 0
fschar = true
if state == :ST_START
state = :ST_DATA
elsif state == :ST_QUOTE
raise IllegalFormatError
end
end
if !rschar and c == rs_str[0]
rs_idx = 0
rschar = true
if state == :ST_START
state = :ST_DATA
elsif state == :ST_QUOTE
raise IllegalFormatError
end
end
end
if c == ?"
fs_idx = rs_idx = 0
if cr
raise IllegalFormatError
end
cell << src[last_idx, (idx - last_idx)]
last_idx = idx
if state == :ST_DATA
if quoted
last_idx += 1
quoted = false
state = :ST_QUOTE
else
raise IllegalFormatError
end
elsif state == :ST_QUOTE
cell << c.chr
last_idx += 1
quoted = true
state = :ST_DATA
else # :ST_START
quoted = true
last_idx += 1
state = :ST_DATA
end
elsif fschar or rschar
if fschar
fs_idx += 1
end
if rschar
rs_idx += 1
end
sep = nil
if fs_idx == fs_size
if state == :ST_START and rs_idx > 0 and fs_idx < rs_idx
state = :ST_DATA
end
cell << src[last_idx, (idx - last_idx - (fs_size - 1))]
last_idx = idx
fs_idx = rs_idx = 0
if cr
raise IllegalFormatError
end
sep = :DT_COLSEP
elsif rs_idx == rs_size
if state == :ST_START and fs_idx > 0 and rs_idx < fs_idx
state = :ST_DATA
end
if !(rs.nil? and cr)
cell << src[last_idx, (idx - last_idx - (rs_size - 1))]
last_idx = idx
end
fs_idx = rs_idx = 0
sep = :DT_ROWSEP
end
if sep
if state == :ST_DATA
return sep, idx + 1, cell;
elsif state == :ST_QUOTE
return sep, idx + 1, cell;
else # :ST_START
return sep, idx + 1, nil
end
end
elsif rs.nil? and c == ?\r
# special \r treatment for backward compatibility
fs_idx = rs_idx = 0
if cr
raise IllegalFormatError
end
cell << src[last_idx, (idx - last_idx)]
last_idx = idx
if quoted
state = :ST_DATA
else
cr = true
end
else
fs_idx = rs_idx = 0
if state == :ST_DATA or state == :ST_START
if cr
raise IllegalFormatError
end
state = :ST_DATA
else # :ST_QUOTE
raise IllegalFormatError
end
end
idx += 1
end
if state == :ST_START
if fs_idx > 0 or rs_idx > 0
state = :ST_DATA
else
return :DT_EOS, idx, nil
end
elsif quoted
raise IllegalFormatError
elsif cr
raise IllegalFormatError
end
cell << src[last_idx, (idx - last_idx)]
last_idx = idx
return :DT_EOS, idx, cell
end