def parse(&block)
return to_enum(__method__) unless block_given?
return if @parsed
if @return_headers and @headers
headers = Row.new(@headers, @raw_headers, true)
if @unconverted_fields
headers = add_unconverted_fields(headers, [])
end
yield headers
end
row = []
begin
@scanner = build_scanner
skip_needless_lines
start_row
while true
@quoted_column_value = false
@unquoted_column_value = false
value = parse_column_value
if value and @field_size_limit and value.size >= @field_size_limit
raise MalformedCSVError.new("Field size exceeded", @lineno + 1)
end
if parse_column_end
row << value
elsif parse_row_end
if row.empty? and value.nil?
emit_row([], &block) unless @skip_blanks
else
row << value
emit_row(row, &block)
row = []
end
skip_needless_lines
start_row
elsif @scanner.eos?
break if row.empty? and value.nil?
row << value
emit_row(row, &block)
break
else
if @quoted_column_value
message = "Do not allow except col_sep_split_separator " +
"after quoted fields"
raise MalformedCSVError.new(message, @lineno + 1)
elsif @unquoted_column_value and @scanner.scan(@cr_or_lf)
message = "Unquoted fields do not allow \\r or \\n"
raise MalformedCSVError.new(message, @lineno + 1)
elsif @scanner.rest.start_with?(@quote_character)
message = "Illegal quoting"
raise MalformedCSVError.new(message, @lineno + 1)
else
raise MalformedCSVError.new("TODO: Meaningful message",
@lineno + 1)
end
end
end
rescue InvalidEncoding
message = "Invalid byte sequence in #{@encoding}"
raise MalformedCSVError.new(message, @lineno + 1)
end
@parsed = true
end