mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-01 18:44:41 +00:00
Return partial reads
This commit is contained in:
@@ -124,6 +124,7 @@ reader_destroy :: proc(r: ^Reader) {
|
||||
// read reads a single record (a slice of fields) from r
|
||||
//
|
||||
// All \r\n sequences are normalized to \n, including multi-line field
|
||||
@(require_results)
|
||||
read :: proc(r: ^Reader, allocator := context.allocator) -> (record: []string, err: Error) {
|
||||
if r.reuse_record {
|
||||
record, err = _read_record(r, &r.last_record, allocator)
|
||||
@@ -136,6 +137,7 @@ read :: proc(r: ^Reader, allocator := context.allocator) -> (record: []string, e
|
||||
}
|
||||
|
||||
// is_io_error checks where an Error is a specific io.Error kind
|
||||
@(require_results)
|
||||
is_io_error :: proc(err: Error, io_err: io.Error) -> bool {
|
||||
if v, ok := err.(io.Error); ok {
|
||||
return v == io_err
|
||||
@@ -143,10 +145,10 @@ is_io_error :: proc(err: Error, io_err: io.Error) -> bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// read_all reads all the remaining records from r.
|
||||
// Each record is a slice of fields.
|
||||
// read_all is defined to read until an EOF, and does not treat, and does not treat EOF as an error
|
||||
@(require_results)
|
||||
read_all :: proc(r: ^Reader, allocator := context.allocator) -> ([][]string, Error) {
|
||||
context.allocator = allocator
|
||||
records: [dynamic][]string
|
||||
@@ -156,13 +158,18 @@ read_all :: proc(r: ^Reader, allocator := context.allocator) -> ([][]string, Err
|
||||
return records[:], nil
|
||||
}
|
||||
if rerr != nil {
|
||||
return nil, rerr
|
||||
// allow for a partial read
|
||||
if record != nil {
|
||||
append(&records, record)
|
||||
}
|
||||
return records[:], rerr
|
||||
}
|
||||
append(&records, record)
|
||||
}
|
||||
}
|
||||
|
||||
// read reads a single record (a slice of fields) from the provided input.
|
||||
@(require_results)
|
||||
read_from_string :: proc(input: string, record_allocator := context.allocator, buffer_allocator := context.allocator) -> (record: []string, n: int, err: Error) {
|
||||
ir: strings.Reader
|
||||
strings.reader_init(&ir, input)
|
||||
@@ -178,6 +185,7 @@ read_from_string :: proc(input: string, record_allocator := context.allocator, b
|
||||
|
||||
|
||||
// read_all reads all the remaining records from the provided input.
|
||||
@(require_results)
|
||||
read_all_from_string :: proc(input: string, records_allocator := context.allocator, buffer_allocator := context.allocator) -> ([][]string, Error) {
|
||||
ir: strings.Reader
|
||||
strings.reader_init(&ir, input)
|
||||
@@ -189,7 +197,7 @@ read_all_from_string :: proc(input: string, records_allocator := context.allocat
|
||||
return read_all(&r, records_allocator)
|
||||
}
|
||||
|
||||
@private
|
||||
@(private, require_results)
|
||||
is_valid_delim :: proc(r: rune) -> bool {
|
||||
switch r {
|
||||
case 0, '"', '\r', '\n', utf8.RUNE_ERROR:
|
||||
@@ -198,8 +206,9 @@ is_valid_delim :: proc(r: rune) -> bool {
|
||||
return utf8.valid_rune(r)
|
||||
}
|
||||
|
||||
@private
|
||||
@(private, require_results)
|
||||
_read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.allocator) -> ([]string, Error) {
|
||||
@(require_results)
|
||||
read_line :: proc(r: ^Reader) -> ([]byte, io.Error) {
|
||||
if !r.multiline_fields {
|
||||
line, err := bufio.reader_read_slice(&r.r, '\n')
|
||||
@@ -269,6 +278,7 @@ _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.all
|
||||
unreachable()
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
length_newline :: proc(b: []byte) -> int {
|
||||
if len(b) > 0 && b[len(b)-1] == '\n' {
|
||||
return 1
|
||||
@@ -276,6 +286,7 @@ _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.all
|
||||
return 0
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
next_rune :: proc(b: []byte) -> rune {
|
||||
r, _ := utf8.decode_rune(b)
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user