By default, the format recognizes EOLs as \n
var example = """
foo,bar
"Hello, word!",1234.5 + 42
"Something
""else""\", baz
"""
var reader = new CsvReader.from_string(example)
var table = reader.read_all
assert table.header == ["foo","bar"]
assert table.records == [["Hello, word!","1234.5 + 42"],
["Something\n\"else\""," baz"]]
csv :: CsvReader :: defaultinit
csv :: CsvReader :: from_string
Creates a new CSVReader from astring
data
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
csv :: CsvReader :: defaultinit
core :: Object :: defaultinit
csv :: CsvStream :: defaultinit
csv :: CsvStream :: delimiter=
The character that delimits escaped value.csv :: CsvReader :: from_string
Creates a new CSVReader from astring
data
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
core :: Object :: output_class_name
Display class name on stdout (debug only).csv :: CsvStream :: separator=
The character that split each cell in a record.
# Reads records from a CSV file.
#
# By default, the format recognizes EOLs as `\n`
#
# ~~~nit
# var example = """
# foo,bar
# "Hello, word!",1234.5 + 42
# "Something
# ""else""\", baz
# """
# var reader = new CsvReader.from_string(example)
# var table = reader.read_all
#
# assert table.header == ["foo","bar"]
# assert table.records == [["Hello, word!","1234.5 + 42"],
# ["Something\n\"else\""," baz"]]
# ~~~
class CsvReader
super CsvStream
# The input stream.
var istream: Reader
# Do we skip the empty lines?
#
# Note: Even if this attribute is `false`, the presence of an line ending at
# end of the last record does not change the number of returned record.
# This is because the line endings are processed as terminators, not as
# separators. Therefore, when there is more than one line ending at the end
# of the file, the additional lines are interpreted as empty records that
# are skipped only if `skip_empty` is set to `true`.
#
# `false` by default.
var skip_empty: Bool = false is writable
# Creates a new CSVReader from a `string` data
init from_string(s: String) do init(new StringReader(s))
# Reads the content of the Stream and interprets it as a CSV Document
#
# Optional parameter `has_header` determines whether the first line
# of the CSV Document is header data.
# Defaults to true
fun read_all(has_header: nullable Bool): CsvDocument do
var header: nullable Array[String] = null
if has_header == null then has_header = true
var iss = istream
var res_data = new Array[Array[String]]
var eol_st = eol.first
var line = new Array[String]
var esc = delimiter
var sep = separator
var eol = eol
var is_eol = false
var eol_buf = new Buffer.with_cap(eol.length)
var c = iss.read_char
var el = new Buffer
while not iss.eof do
if c == null then continue
loop
if c == esc then
c = iss.read_char
loop
if c == esc then
c = iss.read_char
if c != esc then break
end
if c == null then break
el.add c
c = iss.read_char
end
end
if c == sep then break
if c == eol_st then
eol_buf.add c.as(not null)
is_eol = true
for i in [1 .. eol.length[ do
c = iss.read_char
if c == null or c != eol[i] then
is_eol = false
el.append(eol_buf)
eol_buf.clear
break
end
eol_buf.add c
end
if not is_eol then continue
eol_buf.clear
break
end
if c == sep then break
el.add c.as(not null)
c = iss.read_char
if c == null then break
end
line.add el.to_s
el.clear
if is_eol or iss.eof then
c = iss.read_char
is_eol = false
if skip_empty and line.is_empty then
continue
end
if has_header and header == null then
header = line
else res_data.add line
line = new Array[String]
end
if c == sep then c = iss.read_char
end
if header == null then header = new Array[String]
var doc = new CsvDocument
doc.header = header
doc.records = res_data
return doc
end
end
lib/csv/csv.nit:225,1--342,3