mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
documentation for the rest of the strings library
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user