diff options
| author | Michael Kutowski <skytrias@protonmail.com> | 2022-04-03 19:37:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-03 19:37:54 +0200 |
| commit | b5aa50aaa44211bb7db37569722b255262a59d09 (patch) | |
| tree | 0da4972e21737bd7b2c5c0452a5e4b75968fa9af /core/strings/reader.odin | |
| parent | ab91fa6ad513737486bf3a97ee1401554dacc56a (diff) | |
documentation for the rest of the strings library
Diffstat (limited to 'core/strings/reader.odin')
| -rw-r--r-- | core/strings/reader.odin | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/core/strings/reader.odin b/core/strings/reader.odin index ba266c0b5..9b2e10b68 100644 --- a/core/strings/reader.odin +++ b/core/strings/reader.odin @@ -3,46 +3,60 @@ package strings import "core:io" import "core:unicode/utf8" +/* + io stream data for a string reader that can read based on bytes or runes + implements the vtable when using the io.Reader variants + "read" calls advance the current reading offset `i` +*/ Reader :: struct { s: string, // read-only buffer i: i64, // current reading index prev_rune: int, // previous reading index of rune or < 0 } +// init the reader to the string `s` reader_init :: proc(r: ^Reader, s: string) { r.s = s r.i = 0 r.prev_rune = -1 } +// returns a stream from the reader data reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) { s.stream_data = r s.stream_vtable = _reader_vtable return } +// init a reader to the string `s` and return an io.Reader to_reader :: proc(r: ^Reader, s: string) -> io.Reader { reader_init(r, s) rr, _ := io.to_reader(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Reader_At to_reader_at :: proc(r: ^Reader, s: string) -> io.Reader_At { reader_init(r, s) rr, _ := io.to_reader_at(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Byte_Reader to_byte_reader :: proc(r: ^Reader, s: string) -> io.Byte_Reader { reader_init(r, s) rr, _ := io.to_byte_reader(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Rune_Reader to_rune_reader :: proc(r: ^Reader, s: string) -> io.Rune_Reader { reader_init(r, s) rr, _ := io.to_rune_reader(reader_to_stream(r)) return rr } - +// remaining length of the reader reader_length :: proc(r: ^Reader) -> int { if r.i >= i64(len(r.s)) { return 0 @@ -50,10 +64,13 @@ reader_length :: proc(r: ^Reader) -> int { return int(i64(len(r.s)) - r.i) } +// returns the string length stored by the reader reader_size :: proc(r: ^Reader) -> i64 { return i64(len(r.s)) } +// reads len(p) bytes into the slice from the string in the reader +// returns `n` amount of read bytes and an io.Error reader_read :: proc(r: ^Reader, p: []byte) -> (n: int, err: io.Error) { if r.i >= i64(len(r.s)) { return 0, .EOF @@ -63,6 +80,9 @@ reader_read :: proc(r: ^Reader, p: []byte) -> (n: int, err: io.Error) { r.i += i64(n) return } + +// reads len(p) bytes into the slice from the string in the reader at an offset +// returns `n` amount of read bytes and an io.Error reader_read_at :: proc(r: ^Reader, p: []byte, off: i64) -> (n: int, err: io.Error) { if off < 0 { return 0, .Invalid_Offset @@ -76,6 +96,8 @@ reader_read_at :: proc(r: ^Reader, p: []byte, off: i64) -> (n: int, err: io.Erro } return } + +// reads and returns a single byte - error when out of bounds reader_read_byte :: proc(r: ^Reader) -> (byte, io.Error) { r.prev_rune = -1 if r.i >= i64(len(r.s)) { @@ -85,6 +107,8 @@ reader_read_byte :: proc(r: ^Reader) -> (byte, io.Error) { r.i += 1 return b, nil } + +// decreases the reader offset - error when below 0 reader_unread_byte :: proc(r: ^Reader) -> io.Error { if r.i <= 0 { return .Invalid_Unread @@ -93,6 +117,8 @@ reader_unread_byte :: proc(r: ^Reader) -> io.Error { r.i -= 1 return nil } + +// reads and returns a single rune and the rune size - error when out bounds reader_read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: io.Error) { if r.i >= i64(len(r.s)) { r.prev_rune = -1 @@ -107,6 +133,9 @@ reader_read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: io.Error) { r.i += i64(size) return } + +// decreases the reader offset by the last rune +// can only be used once and after a valid read_rune call reader_unread_rune :: proc(r: ^Reader) -> io.Error { if r.i <= 0 { return .Invalid_Unread @@ -118,6 +147,8 @@ reader_unread_rune :: proc(r: ^Reader) -> io.Error { r.prev_rune = -1 return nil } + +// seeks the reader offset to a wanted offset reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { r.prev_rune = -1 abs: i64 @@ -138,6 +169,8 @@ reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, io.E r.i = abs return abs, nil } + +// writes the string content left to read into the io.Writer `w` reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { r.prev_rune = -1 if r.i >= i64(len(r.s)) { @@ -157,7 +190,6 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { return } - @(private) _reader_vtable := &io.Stream_VTable{ impl_size = proc(s: io.Stream) -> i64 { |