aboutsummaryrefslogtreecommitdiff
path: root/core/strings/reader.odin
diff options
context:
space:
mode:
authorMichael Kutowski <skytrias@protonmail.com>2022-04-03 19:37:54 +0200
committerGitHub <noreply@github.com>2022-04-03 19:37:54 +0200
commitb5aa50aaa44211bb7db37569722b255262a59d09 (patch)
tree0da4972e21737bd7b2c5c0452a5e4b75968fa9af /core/strings/reader.odin
parentab91fa6ad513737486bf3a97ee1401554dacc56a (diff)
documentation for the rest of the strings library
Diffstat (limited to 'core/strings/reader.odin')
-rw-r--r--core/strings/reader.odin36
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 {