diff --git a/core/bufio/read_writer.odin b/core/bufio/read_writer.odin index f9ae1ed45..3e6bd3aa0 100644 --- a/core/bufio/read_writer.odin +++ b/core/bufio/read_writer.odin @@ -14,51 +14,29 @@ read_writer_init :: proc(rw: ^Read_Writer, r: ^Reader, w: ^Writer) { } read_writer_to_stream :: proc(rw: ^Read_Writer) -> (s: io.Stream) { - s.stream_data = rw - s.stream_vtable = &_read_writer_vtable + s.procedure = _read_writer_procedure + s.data = rw return } @(private) -_read_writer_vtable := io.Stream_VTable{ - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Read_Writer)(s.stream_data).r - return reader_read(b, p) - }, - impl_unread_byte = proc(s: io.Stream) -> io.Error { - b := (^Read_Writer)(s.stream_data).r - return reader_unread_byte(b) - }, - impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) { - b := (^Read_Writer)(s.stream_data).r - return reader_read_rune(b) - }, - impl_unread_rune = proc(s: io.Stream) -> io.Error { - b := (^Read_Writer)(s.stream_data).r - return reader_unread_rune(b) - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - b := (^Read_Writer)(s.stream_data).r - return reader_write_to(b, w) - }, - impl_flush = proc(s: io.Stream) -> io.Error { - b := (^Read_Writer)(s.stream_data).w - return writer_flush(b) - }, - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Read_Writer)(s.stream_data).w - return writer_write(b, p) - }, - impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error { - b := (^Read_Writer)(s.stream_data).w - return writer_write_byte(b, c) - }, - impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) { - b := (^Read_Writer)(s.stream_data).w - return writer_write_rune(b, r) - }, - impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) { - b := (^Read_Writer)(s.stream_data).w - return writer_read_from(b, r) - }, -} +_read_writer_procedure := proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + rw := (^Read_Writer)(stream_data) + n_int: int + #partial switch mode { + case .Flush: + err = writer_flush(rw.w) + return + case .Read: + n_int, err = reader_read(rw.r, p) + n = i64(n_int) + return + case .Write: + n_int, err = writer_write(rw.w, p) + n = i64(n_int) + return + case .Query: + return io.query_utility({.Flush, .Read, .Write, .Query}) + } + return 0, .Empty +} \ No newline at end of file diff --git a/core/bufio/reader.odin b/core/bufio/reader.odin index 6bfc4cd9d..dc4e02c02 100644 --- a/core/bufio/reader.odin +++ b/core/bufio/reader.odin @@ -311,18 +311,6 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { } m: i64 - if nr, ok := io.to_writer_to(b.rd); ok { - m, err = io.write_to(nr, w) - n += m - return n, err - } - - if nw, ok := io.to_reader_from(w); ok { - m, err = io.read_from(nw, b.rd) - n += m - return n, err - } - if b.w-b.r < len(b.buf) { if err = _reader_read_new_chunk(b); err != nil { return @@ -352,48 +340,28 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { // reader_to_stream converts a Reader into an io.Stream reader_to_stream :: proc(b: ^Reader) -> (s: io.Stream) { - s.stream_data = b - s.stream_vtable = &_reader_vtable + s.data = b + s.procedure = _reader_proc return } @(private) -_reader_vtable := io.Stream_VTable{ - impl_destroy = proc(s: io.Stream) -> io.Error { - b := (^Reader)(s.stream_data) +_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + b := (^Reader)(stream_data) + #partial switch mode { + case .Read: + return io._i64_err(reader_read(b, p)) + case .Destroy: reader_destroy(b) - return nil - }, - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Reader)(s.stream_data) - return reader_read(b, p) - }, - impl_read_byte = proc(s: io.Stream) -> (c: byte, err: io.Error) { - b := (^Reader)(s.stream_data) - return reader_read_byte(b) - }, - impl_unread_byte = proc(s: io.Stream) -> io.Error { - b := (^Reader)(s.stream_data) - return reader_unread_byte(b) - }, - impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) { - b := (^Reader)(s.stream_data) - return reader_read_rune(b) - }, - impl_unread_rune = proc(s: io.Stream) -> io.Error { - b := (^Reader)(s.stream_data) - return reader_unread_rune(b) - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - b := (^Reader)(s.stream_data) - return reader_write_to(b, w) - }, + return + case .Query: + return io.query_utility({.Read, .Destroy, .Query}) + } + return 0, .Empty } - - // // Utility procedures // diff --git a/core/bufio/writer.odin b/core/bufio/writer.odin index ed0d557c5..bfa8b804f 100644 --- a/core/bufio/writer.odin +++ b/core/bufio/writer.odin @@ -173,14 +173,6 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) { if b.err != nil { return 0, b.err } - if writer_buffered(b) == 0 { - if w, ok := io.to_reader_from(b.wr); !ok { - n, err = io.read_from(w, r) - b.err = err - return - } - } - for { if writer_available(b) == 0 { writer_flush(b) or_return @@ -222,46 +214,35 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) { // writer_to_stream converts a Writer into an io.Stream writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) { - s.stream_data = b - s.stream_vtable = &_writer_vtable + s.data = b + s.procedure = _writer_proc return } // writer_to_stream converts a Writer into an io.Stream writer_to_writer :: proc(b: ^Writer) -> (s: io.Writer) { - s.stream_data = b - s.stream_vtable = &_writer_vtable - return + return writer_to_stream(b) } - @(private) -_writer_vtable := io.Stream_VTable{ - impl_destroy = proc(s: io.Stream) -> io.Error { - b := (^Writer)(s.stream_data) +_writer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + b := (^Writer)(stream_data) + #partial switch mode { + case .Flush: + err = writer_flush(b) + return + case .Write: + n_int: int + n_int, err = writer_write(b, p) + n = i64(n_int) + return + case .Destroy: writer_destroy(b) - return nil - }, - impl_flush = proc(s: io.Stream) -> io.Error { - b := (^Writer)(s.stream_data) - return writer_flush(b) - }, - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Writer)(s.stream_data) - return writer_write(b, p) - }, - impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error { - b := (^Writer)(s.stream_data) - return writer_write_byte(b, c) - }, - impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) { - b := (^Writer)(s.stream_data) - return writer_write_rune(b, r) - }, - impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) { - b := (^Writer)(s.stream_data) - return writer_read_from(b, r) - }, + return + case .Query: + return io.query_utility({.Flush, .Write, .Destroy, .Query}) + } + return 0, .Empty } diff --git a/core/bytes/buffer.odin b/core/bytes/buffer.odin index b60a8e877..4375d8195 100644 --- a/core/bytes/buffer.odin +++ b/core/bytes/buffer.odin @@ -375,69 +375,31 @@ buffer_read_from :: proc(b: ^Buffer, r: io.Reader) -> (n: i64, err: io.Error) #n buffer_to_stream :: proc(b: ^Buffer) -> (s: io.Stream) { - s.stream_data = b - s.stream_vtable = &_buffer_vtable + s.data = b + s.procedure = _buffer_proc return } @(private) -_buffer_vtable := io.Stream_VTable{ - impl_size = proc(s: io.Stream) -> i64 { - b := (^Buffer)(s.stream_data) - return i64(buffer_capacity(b)) - }, - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_read(b, p) - }, - impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_read_at(b, p, int(offset)) - }, - impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_read_byte(b) - }, - impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_read_rune(b) - }, - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_write(b, p) - }, - impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_write_at(b, p, int(offset)) - }, - impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error { - b := (^Buffer)(s.stream_data) - return buffer_write_byte(b, c) - }, - impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_write_rune(b, r) - }, - impl_unread_byte = proc(s: io.Stream) -> io.Error { - b := (^Buffer)(s.stream_data) - return buffer_unread_byte(b) - }, - impl_unread_rune = proc(s: io.Stream) -> io.Error { - b := (^Buffer)(s.stream_data) - return buffer_unread_rune(b) - }, - impl_destroy = proc(s: io.Stream) -> io.Error { - b := (^Buffer)(s.stream_data) +_buffer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + b := (^Buffer)(stream_data) + #partial switch mode { + case .Read: + return io._i64_err(buffer_read(b, p)) + case .Read_At: + return io._i64_err(buffer_read_at(b, p, int(offset))) + case .Write: + return io._i64_err(buffer_write(b, p)) + case .Write_At: + return io._i64_err(buffer_write_at(b, p, int(offset))) + case .Size: + n = i64(buffer_capacity(b)) + return + case .Destroy: buffer_destroy(b) - return nil - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_write_to(b, w) - }, - impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) { - b := (^Buffer)(s.stream_data) - return buffer_read_from(b, r) - }, + return + case .Query: + return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Size, .Destroy}) + } + return 0, .Empty } - diff --git a/core/bytes/reader.odin b/core/bytes/reader.odin index 7c37f3061..4b18345ba 100644 --- a/core/bytes/reader.odin +++ b/core/bytes/reader.odin @@ -16,8 +16,8 @@ reader_init :: proc(r: ^Reader, s: []byte) { } reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) { - s.stream_data = r - s.stream_vtable = &_reader_vtable + s.data = r + s.procedure = _reader_proc return } @@ -137,41 +137,22 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { @(private) -_reader_vtable := io.Stream_VTable{ - impl_size = proc(s: io.Stream) -> i64 { - r := (^Reader)(s.stream_data) - return reader_size(r) - }, - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read(r, p) - }, - impl_read_at = proc(s: io.Stream, p: []byte, off: i64) -> (n: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_at(r, p, off) - }, - impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_byte(r) - }, - impl_unread_byte = proc(s: io.Stream) -> io.Error { - r := (^Reader)(s.stream_data) - return reader_unread_byte(r) - }, - impl_read_rune = proc(s: io.Stream) -> (ch: rune, size: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_rune(r) - }, - impl_unread_rune = proc(s: io.Stream) -> io.Error { - r := (^Reader)(s.stream_data) - return reader_unread_rune(r) - }, - impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { - r := (^Reader)(s.stream_data) - return reader_seek(r, offset, whence) - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_write_to(r, w) - }, +_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + r := (^Reader)(stream_data) + #partial switch mode { + case .Read: + return io._i64_err(reader_read(r, p)) + case .Read_At: + return io._i64_err(reader_read_at(r, p, offset)) + case .Seek: + n, err = reader_seek(r, offset, whence) + return + case .Size: + n = reader_size(r) + return + case .Query: + return io.query_utility({.Read, .Read_At, .Seek, .Size, .Query}) + } + return 0, .Empty } + diff --git a/core/compress/common.odin b/core/compress/common.odin index 6bcc46bf2..bc56229c2 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -188,7 +188,8 @@ input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Erro } input_size_from_stream :: proc(z: ^Context_Stream_Input) -> (res: i64, err: Error) { - return io.size(z.input), nil + res, _ = io.size(z.input) + return } input_size :: proc{input_size_from_memory, input_size_from_stream} @@ -215,7 +216,7 @@ read_slice_from_stream :: #force_inline proc(z: ^Context_Stream_Input, size: int // TODO: REMOVE ALL USE OF context.temp_allocator here // the is literally no need for it b := make([]u8, size, context.temp_allocator) - _, e := z.input->impl_read(b[:]) + _, e := io.read(z.input, b[:]) if e == .None { return b, .None } diff --git a/core/crypto/blake/blake.odin b/core/crypto/blake/blake.odin index 5fc0a02b9..3685109e4 100644 --- a/core/crypto/blake/blake.odin +++ b/core/crypto/blake/blake.odin @@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin index e75d74197..8f0770f82 100644 --- a/core/crypto/blake2b/blake2b.odin +++ b/core/crypto/blake2b/blake2b.odin @@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _blake2.update(&ctx, buf[:read]) } diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin index 831335081..6a2d4ab9b 100644 --- a/core/crypto/blake2s/blake2s.odin +++ b/core/crypto/blake2s/blake2s.odin @@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _blake2.update(&ctx, buf[:read]) } diff --git a/core/crypto/gost/gost.odin b/core/crypto/gost/gost.odin index 1d0274fae..5aca8ce95 100644 --- a/core/crypto/gost/gost.odin +++ b/core/crypto/gost/gost.odin @@ -65,7 +65,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/groestl/groestl.odin b/core/crypto/groestl/groestl.odin index 8e5a2440d..61460808f 100644 --- a/core/crypto/groestl/groestl.odin +++ b/core/crypto/groestl/groestl.odin @@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/haval/haval.odin b/core/crypto/haval/haval.odin index 811ecf95d..b98facb33 100644 --- a/core/crypto/haval/haval.odin +++ b/core/crypto/haval/haval.odin @@ -79,7 +79,7 @@ hash_stream_128_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -164,7 +164,7 @@ hash_stream_128_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -249,7 +249,7 @@ hash_stream_128_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -334,7 +334,7 @@ hash_stream_160_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -419,7 +419,7 @@ hash_stream_160_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -504,7 +504,7 @@ hash_stream_160_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -589,7 +589,7 @@ hash_stream_192_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -674,7 +674,7 @@ hash_stream_192_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -759,7 +759,7 @@ hash_stream_192_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -844,7 +844,7 @@ hash_stream_224_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -929,7 +929,7 @@ hash_stream_224_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -1014,7 +1014,7 @@ hash_stream_224_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -1099,7 +1099,7 @@ hash_stream_256_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -1184,7 +1184,7 @@ hash_stream_256_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) @@ -1270,7 +1270,7 @@ hash_stream_256_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) ctx.str_len = u32(len(buf[:read])) if read > 0 { update(&ctx, buf[:read]) diff --git a/core/crypto/jh/jh.odin b/core/crypto/jh/jh.odin index 42c2d1d34..5dc6c4e6b 100644 --- a/core/crypto/jh/jh.odin +++ b/core/crypto/jh/jh.odin @@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/keccak/keccak.odin b/core/crypto/keccak/keccak.odin index aeb5aac52..4c74858d2 100644 --- a/core/crypto/keccak/keccak.odin +++ b/core/crypto/keccak/keccak.odin @@ -77,7 +77,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -159,7 +159,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -241,7 +241,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -323,7 +323,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } diff --git a/core/crypto/md2/md2.odin b/core/crypto/md2/md2.odin index 711e6e9f6..4942183e1 100644 --- a/core/crypto/md2/md2.odin +++ b/core/crypto/md2/md2.odin @@ -64,7 +64,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/md4/md4.odin b/core/crypto/md4/md4.odin index b2651225b..8efdbb5a5 100644 --- a/core/crypto/md4/md4.odin +++ b/core/crypto/md4/md4.odin @@ -68,7 +68,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/md5/md5.odin b/core/crypto/md5/md5.odin index 30a556102..858480b04 100644 --- a/core/crypto/md5/md5.odin +++ b/core/crypto/md5/md5.odin @@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/ripemd/ripemd.odin b/core/crypto/ripemd/ripemd.odin index 702d29037..f9edb121b 100644 --- a/core/crypto/ripemd/ripemd.odin +++ b/core/crypto/ripemd/ripemd.odin @@ -69,7 +69,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -145,7 +145,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -221,7 +221,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -297,7 +297,7 @@ hash_stream_320 :: proc(s: io.Stream) -> ([DIGEST_SIZE_320]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/sha1/sha1.odin b/core/crypto/sha1/sha1.odin index b0dbd7dc8..599d1791e 100644 --- a/core/crypto/sha1/sha1.odin +++ b/core/crypto/sha1/sha1.odin @@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index 9792a4cb8..0f55c4be1 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -74,7 +74,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -153,7 +153,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -232,7 +232,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -311,7 +311,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index 1202f8b23..5d8ad2106 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -73,7 +73,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -152,7 +152,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -231,7 +231,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -310,7 +310,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index 525dcfbd3..020ba68f3 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -73,7 +73,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } @@ -155,7 +155,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _sha3.update(&ctx, buf[:read]) } diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin index 74c9f22e2..9e684ff08 100644 --- a/core/crypto/sm3/sm3.odin +++ b/core/crypto/sm3/sm3.odin @@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/streebog/streebog.odin b/core/crypto/streebog/streebog.odin index f85977cba..42da1e695 100644 --- a/core/crypto/streebog/streebog.odin +++ b/core/crypto/streebog/streebog.odin @@ -70,7 +70,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } @@ -146,7 +146,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/crypto/tiger/tiger.odin b/core/crypto/tiger/tiger.odin index cf6159fad..614926129 100644 --- a/core/crypto/tiger/tiger.odin +++ b/core/crypto/tiger/tiger.odin @@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } @@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } @@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } diff --git a/core/crypto/tiger2/tiger2.odin b/core/crypto/tiger2/tiger2.odin index e8f2c4edb..ead874d56 100644 --- a/core/crypto/tiger2/tiger2.odin +++ b/core/crypto/tiger2/tiger2.odin @@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } @@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } @@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { _tiger.update(&ctx, buf[:read]) } diff --git a/core/crypto/whirlpool/whirlpool.odin b/core/crypto/whirlpool/whirlpool.odin index 0cfef7c6b..cf0bf6490 100644 --- a/core/crypto/whirlpool/whirlpool.odin +++ b/core/crypto/whirlpool/whirlpool.odin @@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) read := 1 for read > 0 { - read, _ = s->impl_read(buf) + read, _ = io.read(s, buf) if read > 0 { update(&ctx, buf[:read]) } diff --git a/core/fmt/fmt_os.odin b/core/fmt/fmt_os.odin index 5b3a68502..840fd1545 100644 --- a/core/fmt/fmt_os.odin +++ b/core/fmt/fmt_os.odin @@ -12,7 +12,7 @@ fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int { b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:]) + bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) w := bufio.writer_to_writer(&b) return wprint(w, ..args, sep=sep) } @@ -23,7 +23,7 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int { b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:]) + bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) w := bufio.writer_to_writer(&b) return wprintln(w, ..args, sep=sep) @@ -34,7 +34,7 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:]) + bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) w := bufio.writer_to_writer(&b) return wprintf(w, fmt, ..args) @@ -44,7 +44,7 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:]) + bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) w := bufio.writer_to_writer(&b) return wprint_type(w, info) @@ -54,7 +54,7 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) { b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:]) + bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) w := bufio.writer_to_writer(&b) return wprint_typeid(w, id) diff --git a/core/io/conv.odin b/core/io/conv.odin index 39a72d69d..e3286baca 100644 --- a/core/io/conv.odin +++ b/core/io/conv.odin @@ -1,124 +1,80 @@ package io to_reader :: proc(s: Stream) -> (r: Reader, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read == nil { - ok = false - } + r = s + ok = .Read in query(s) return } to_writer :: proc(s: Stream) -> (w: Writer, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write == nil { - ok = false - } + w = s + ok = .Write in query(s) return } to_closer :: proc(s: Stream) -> (c: Closer, ok: bool = true) #optional_ok { - c.stream = s - if s.stream_vtable == nil || s.impl_close == nil { - ok = false - } + c = s + ok = .Close in query(s) return } to_flusher :: proc(s: Stream) -> (f: Flusher, ok: bool = true) #optional_ok { - f.stream = s - if s.stream_vtable == nil || s.impl_flush == nil { - ok = false - } + f = s + ok = .Flush in query(s) return } to_seeker :: proc(s: Stream) -> (seeker: Seeker, ok: bool = true) #optional_ok { - seeker.stream = s - if s.stream_vtable == nil || s.impl_seek == nil { - ok = false - } + seeker = s + ok = .Seek in query(s) return } to_read_writer :: proc(s: Stream) -> (r: Read_Writer, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil { - ok = false - } + r = s + ok = query(s) >= {.Read, .Write} return } to_read_closer :: proc(s: Stream) -> (r: Read_Closer, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read == nil || s.impl_close == nil { - ok = false - } + r = s + ok = query(s) >= {.Read, .Close} return } to_read_write_closer :: proc(s: Stream) -> (r: Read_Write_Closer, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_close == nil { - ok = false - } + r = s + ok = query(s) >= {.Read, .Write, .Close} return } to_read_write_seeker :: proc(s: Stream) -> (r: Read_Write_Seeker, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_seek == nil { - ok = false - } + r = s + ok = query(s) >= {.Read, .Write, .Seek} return } to_write_flusher :: proc(s: Stream) -> (w: Write_Flusher, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil { - ok = false - } + w = s + ok = query(s) >= {.Write, .Flush} return } to_write_flush_closer :: proc(s: Stream) -> (w: Write_Flush_Closer, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil || s.impl_close == nil { - ok = false - } + w = s + ok = query(s) >= {.Write, .Flush, .Close} return } to_reader_at :: proc(s: Stream) -> (r: Reader_At, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read_at == nil { - ok = false - } + r = s + ok = query(s) >= {.Read_At} return } to_writer_at :: proc(s: Stream) -> (w: Writer_At, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write_at == nil { - ok = false - } - return -} -to_reader_from :: proc(s: Stream) -> (r: Reader_From, ok: bool = true) #optional_ok { - r.stream = s - if s.stream_vtable == nil || s.impl_read_from == nil { - ok = false - } - return -} -to_writer_to :: proc(s: Stream) -> (w: Writer_To, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write_to == nil { - ok = false - } + w = s + ok = query(s) >= {.Write_At} return } to_write_closer :: proc(s: Stream) -> (w: Write_Closer, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write == nil || s.impl_close == nil { - ok = false - } + w = s + ok = query(s) >= {.Write, .Close} return } to_write_seeker :: proc(s: Stream) -> (w: Write_Seeker, ok: bool = true) #optional_ok { - w.stream = s - if s.stream_vtable == nil || s.impl_write == nil || s.impl_seek == nil { - ok = false - } + w = s + ok = query(s) >= {.Write, .Seek} return } diff --git a/core/io/io.odin b/core/io/io.odin index 7faa500b1..566e13c54 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -53,137 +53,106 @@ Error :: enum i32 { Empty = -1, } -Close_Proc :: proc(using s: Stream) -> Error -Flush_Proc :: proc(using s: Stream) -> Error -Seek_Proc :: proc(using s: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error) -Size_Proc :: proc(using s: Stream) -> i64 -Read_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error) -Read_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error) -Read_From_Proc :: proc(using s: Stream, r: Reader) -> (n: i64, err: Error) -Read_Byte_Proc :: proc(using s: Stream) -> (byte, Error) -Read_Rune_Proc :: proc(using s: Stream) -> (ch: rune, size: int, err: Error) -Unread_Byte_Proc :: proc(using s: Stream) -> Error -Unread_Rune_Proc :: proc(using s: Stream) -> Error -Write_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error) -Write_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error) -Write_To_Proc :: proc(using s: Stream, w: Writer) -> (n: i64, err: Error) -Write_Byte_Proc :: proc(using s: Stream, c: byte) -> Error -Write_Rune_Proc :: proc(using s: Stream, r: rune) -> (size: int, err: Error) -Destroy_Proc :: proc(using s: Stream) -> Error +Stream_Mode :: enum { + Close, + Flush, + Read, + Read_At, + Write, + Write_At, + Seek, + Size, + Destroy, + Query, // query what modes are available +} +Stream_Mode_Set :: distinct bit_set[Stream_Mode; i64] + +Stream_Proc :: #type proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) Stream :: struct { - using stream_vtable: ^Stream_VTable, - stream_data: rawptr, -} -Stream_VTable :: struct { - impl_close: Close_Proc, - impl_flush: Flush_Proc, - - impl_seek: Seek_Proc, - impl_size: Size_Proc, - - impl_read: Read_Proc, - impl_read_at: Read_At_Proc, - impl_read_byte: Read_Byte_Proc, - impl_read_rune: Read_Rune_Proc, - impl_write_to: Write_To_Proc, - - impl_write: Write_Proc, - impl_write_at: Write_At_Proc, - impl_write_byte: Write_Byte_Proc, - impl_write_rune: Write_Rune_Proc, - impl_read_from: Read_From_Proc, - - impl_unread_byte: Unread_Byte_Proc, - impl_unread_rune: Unread_Rune_Proc, - - impl_destroy: Destroy_Proc, + procedure: Stream_Proc, + data: rawptr, } +Reader :: Stream +Writer :: Stream +Closer :: Stream +Flusher :: Stream +Seeker :: Stream -Reader :: struct {using stream: Stream} -Writer :: struct {using stream: Stream} -Closer :: struct {using stream: Stream} -Flusher :: struct {using stream: Stream} -Seeker :: struct {using stream: Stream} +Read_Writer :: Stream +Read_Closer :: Stream +Read_Write_Closer :: Stream +Read_Write_Seeker :: Stream -Read_Writer :: struct {using stream: Stream} -Read_Closer :: struct {using stream: Stream} -Read_Write_Closer :: struct {using stream: Stream} -Read_Write_Seeker :: struct {using stream: Stream} +Write_Closer :: Stream +Write_Seeker :: Stream +Write_Flusher :: Stream +Write_Flush_Closer :: Stream -Write_Closer :: struct {using stream: Stream} -Write_Seeker :: struct {using stream: Stream} -Write_Flusher :: struct {using stream: Stream} -Write_Flush_Closer :: struct {using stream: Stream} - -Reader_At :: struct {using stream: Stream} -Writer_At :: struct {using stream: Stream} -Reader_From :: struct {using stream: Stream} -Writer_To :: struct {using stream: Stream} +Reader_At :: Stream +Writer_At :: Stream -destroy :: proc(s: Stream) -> Error { - close_err := close({s}) - if s.stream_vtable != nil && s.impl_destroy != nil { - return s->impl_destroy() +destroy :: proc(s: Stream) -> (err: Error) { + _ = flush(s) + _ = close(s) + if s.procedure != nil { + _, err = s.procedure(s.data, .Destroy, nil, 0, nil) + } else { + err = .Empty } - if close_err != .None { - return close_err - } - return .Empty + return } +query :: proc(s: Stream) -> (set: Stream_Mode_Set) { + if s.procedure != nil { + n, _ := s.procedure(s.data, .Query, nil, 0, nil) + set = transmute(Stream_Mode_Set)n + if set != nil { + set += {.Query} + } + } + return +} + +query_utility :: #force_inline proc "contextless" (set: Stream_Mode_Set) -> (n: i64, err: Error) { + return transmute(i64)set, nil +} + +_i64_err :: #force_inline proc "contextless" (n: int, err: Error) -> (i64, Error) { + return i64(n), err +} + + // read reads up to len(p) bytes into s. It returns the number of bytes read and any error if occurred. // // When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of // bytes read along with the error. read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) { - if s.stream_vtable != nil { - if s.impl_read != nil { - n, err = s->impl_read(p) - if n_read != nil { - n_read^ += n - } - return - } else if s.impl_read_byte != nil { - bytes_read := 0 - defer if n_read != nil { - n_read^ += bytes_read - } - for _, i in p { - p[i] = s->impl_read_byte() or_return - bytes_read += 1 - } - return - } + if s.procedure != nil { + n64: i64 + n64, err = s.procedure(s.data, .Read, p, 0, nil) + n = int(n64) + if n_read != nil { n_read^ += n } + } else { + err = .Empty } - return 0, .Empty + return } // write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred. write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) { - if s.stream_vtable != nil { - if s.impl_write != nil { - n, err = s->impl_write(p) - if n_written != nil { - n_written^ += n - } - return - } else if s.impl_write_byte != nil { - bytes_written := 0 - defer if n_written != nil { - n_written^ += bytes_written - } - for c in p { - s->impl_write_byte(c) or_return - bytes_written += 1 - } - return - } + if s.procedure != nil { + n64: i64 + n64, err = s.procedure(s.data, .Write, p, 0, nil) + n = int(n64) + if n_written != nil { n_written^ += n } + } else { + err = .Empty } - return 0, .Empty + return } // seek sets the offset of the next read or write to offset. @@ -194,57 +163,45 @@ write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Erro // // seek returns the new offset to the start of the file/stream, and any error if occurred. seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { - if s.stream_vtable != nil && s.impl_seek != nil { - return s->impl_seek(offset, whence) + if s.procedure != nil { + n, err = s.procedure(s.data, .Seek, nil, offset, whence) + } else { + err = .Empty } - return 0, .Empty + return } // The behaviour of close after the first call is stream implementation defined. // Different streams may document their own behaviour. -close :: proc(s: Closer) -> Error { - if s.stream_vtable != nil && s.impl_close != nil { - return s->impl_close() +close :: proc(s: Closer) -> (err: Error) { + if s.procedure != nil { + _, err = s.procedure(s.data, .Close, nil, 0, nil) } - // Instead of .Empty, .None is fine in this case - return .None + return } -flush :: proc(s: Flusher) -> Error { - if s.stream_vtable != nil && s.impl_flush != nil { - return s->impl_flush() +flush :: proc(s: Flusher) -> (err: Error) { + if s.procedure != nil { + _, err = s.procedure(s.data, .Flush, nil, 0, nil) } - // Instead of .Empty, .None is fine in this case - return .None + return } // size returns the size of the stream. If the stream does not support querying its size, 0 will be returned. -size :: proc(s: Stream) -> i64 { - if s.stream_vtable == nil { - return 0 +size :: proc(s: Stream) -> (n: i64, err: Error) { + if s.procedure != nil { + n, err = s.procedure(s.data, .Size, nil, 0, nil) + if err == .Empty { + n = 0 + curr := seek(s, 0, .Current) or_return + end := seek(s, 0, .End) or_return + seek(s, curr, .Start) or_return + n = end + } + } else { + err = .Empty } - if s.impl_size != nil { - return s->impl_size() - } - if s.impl_seek == nil { - return 0 - } - - curr, end: i64 - err: Error - if curr, err = s->impl_seek(0, .Current); err != nil { - return 0 - } - - if end, err = s->impl_seek(0, .End); err != nil { - return 0 - } - - if _, err = s->impl_seek(curr, .Start); err != nil { - return 0 - } - - return end + return } @@ -256,29 +213,24 @@ size :: proc(s: Stream) -> i64 { // // If n == len(p), err may be either nil or .EOF read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) { - defer if n_read != nil { - n_read^ += n - } - - if r.stream_vtable == nil { - return 0, .Empty - } - if r.impl_read_at != nil { - return r->impl_read_at(p, offset) - } - if r.impl_seek == nil || r.impl_read == nil { - return 0, .Empty - } - - curr_offset := r->impl_seek(offset, .Current) or_return - - n, err = r->impl_read(p) - _, err1 := r->impl_seek(curr_offset, .Start) - if err1 != nil && err == nil { - err = err1 + if r.procedure != nil { + n64: i64 + n64, err = r.procedure(r.data, .Read_At, p, offset, nil) + if err != .Empty { + n = int(n64) + } else { + curr := seek(r, offset, .Current) or_return + n, err = read(r, p) + _, err1 := seek(r, curr, .Start) + if err1 != nil && err == nil { + err = err1 + } + } + if n_read != nil { n_read^ += n } + } else { + err = .Empty } return - } // write_at writes len(p) bytes into p starting with the provided offset in the underlying Writer_At stream w. @@ -287,97 +239,39 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: // If write_at is writing to a Writer_At which has a seek offset, then write_at should not affect the underlying // seek offset. write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) { - defer if n_written != nil { - n_written^ += n - } - - if w.stream_vtable == nil { - return 0, .Empty - } - if w.impl_write_at != nil { - return w->impl_write_at(p, offset) - } - if w.impl_seek == nil || w.impl_write == nil { - return 0, .Empty - } - - curr_offset: i64 - curr_offset, err = w->impl_seek(offset, .Current) - if err != nil { - return 0, err - } - - n, err = w->impl_write(p) - _, err1 := w->impl_seek(curr_offset, .Start) - if err1 != nil && err == nil { - err = err1 + if w.procedure != nil { + n64: i64 + n64, err = w.procedure(w.data, .Write_At, p, offset, nil) + if err != .Empty { + n = int(n64) + } else { + curr := seek(w, offset, .Current) or_return + n, err = write(w, p) + _, err1 := seek(w, curr, .Start) + if err1 != nil && err == nil { + err = err1 + } + } + if n_written != nil { n_written^ += n } + } else { + err = .Empty } return } -write_to :: proc(r: Writer_To, w: Writer) -> (n: i64, err: Error) { - if r.stream_vtable == nil || w.stream_vtable == nil { - return 0, .Empty - } - if r.impl_write_to != nil { - return r->impl_write_to(w) - } - return 0, .Empty -} -read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) { - if r.stream_vtable == nil || w.stream_vtable == nil { - return 0, .Empty - } - if r.impl_read_from != nil { - return w->impl_read_from(r) - } - return 0, .Empty -} - - // read_byte reads and returns the next byte from r. read_byte :: proc(r: Reader, n_read: ^int = nil) -> (b: byte, err: Error) { - defer if err == nil && n_read != nil { - n_read^ += 1 - } - - if r.stream_vtable == nil { - return 0, .Empty - } - if r.impl_read_byte != nil { - return r->impl_read_byte() - } - if r.impl_read == nil { - return 0, .Empty - } - buf: [1]byte - _, err = r->impl_read(buf[:]) - return buf[0], err + _, err = read(r, buf[:], n_read) + b = buf[0] + return } write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error { - return _write_byte(auto_cast w, c, n_written) -} - -@(private) -_write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> (err: Error) { - defer if err == nil && n_written != nil { - n_written^ += 1 - } - if w.stream_vtable == nil { - return .Empty - } - if w.impl_write_byte != nil { - return w->impl_write_byte(c) - } - if w.impl_write == nil { - return .Empty - } - - b := [1]byte{c} - _, err = w->impl_write(b[:]) - return err + buf: [1]byte + buf[0] = c + write(w, buf[:], n_written) or_return + return nil } // read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes. @@ -385,19 +279,9 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: defer if err == nil && n_read != nil { n_read^ += size } - if br.stream_vtable == nil { - return 0, 0, .Empty - } - if br.impl_read_rune != nil { - return br->impl_read_rune() - } - if br.impl_read == nil { - return 0, 0, .Empty - } b: [utf8.UTF_MAX]byte - _, err = br->impl_read(b[:1]) - + _, err = read(br, b[:1]) s0 := b[0] ch = rune(s0) @@ -415,7 +299,7 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: return } sz := int(x&7) - size, err = br->impl_read(b[1:sz]) + size, err = read(br, b[1:sz]) if err != nil || size+1 < sz { ch = utf8.RUNE_ERROR return @@ -425,28 +309,6 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: return } -unread_byte :: proc(s: Stream) -> Error { - if s.stream_vtable == nil { - return .Empty - } - if s.impl_unread_byte != nil { - return s->impl_unread_byte() - } - if s.impl_seek != nil { - _, err := s->impl_seek(-1, .Current) - return err - } - - return .Empty -} -unread_rune :: proc(s: Writer) -> Error { - if s.stream_vtable != nil && s.impl_unread_rune != nil { - return s->impl_unread_rune() - } - return .Empty -} - - // write_string writes the contents of the string s to w. write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) { return write(s, transmute([]byte)str, n_written) @@ -457,14 +319,6 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err defer if err == nil && n_written != nil { n_written^ += size } - - if s.stream_vtable == nil { - return 0, .Empty - } - if s.impl_write_rune != nil { - return s->impl_write_rune(r) - } - if r < utf8.RUNE_SELF { err = write_byte(s, byte(r)) if err == nil { @@ -542,21 +396,15 @@ copy_n :: proc(dst: Writer, src: Reader, n: i64) -> (written: i64, err: Error) { @(private) _copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, err: Error) { - if dst.stream_vtable == nil || src.stream_vtable == nil { + if dst.procedure == nil || src.procedure == nil { return 0, .Empty } - if src.impl_write_to != nil { - return src->impl_write_to(dst) - } - if src.impl_read_from != nil { - return dst->impl_read_from(src) - } buf := buf if buf == nil { DEFAULT_SIZE :: 4 * 1024 size := DEFAULT_SIZE - if src.stream_vtable == _limited_reader_vtable { - l := (^Limited_Reader)(src.stream_data) + if src.procedure == _limited_reader_proc { + l := (^Limited_Reader)(src.data) if i64(size) > l.n { if l.n < 1 { size = 1 diff --git a/core/io/multi.odin b/core/io/multi.odin index 64c533e37..e85114a7a 100644 --- a/core/io/multi.odin +++ b/core/io/multi.odin @@ -5,33 +5,37 @@ Multi_Reader :: struct { } @(private) -_multi_reader_vtable := &Stream_VTable{ - impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) { - mr := (^Multi_Reader)(s.stream_data) - for len(mr.readers) > 0 { - r := mr.readers[0] - n, err = read(r, p) - if err == .EOF { - ordered_remove(&mr.readers, 0) - } - if n > 0 || err != .EOF { - if err == .EOF && len(mr.readers) > 0 { - // Don't return EOF yet, more readers remain - err = nil - } - return - } +_multi_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { + if mode == .Query { + return query_utility({.Read, .Query}) + } else if mode != .Read { + return 0, .Empty + } + mr := (^Multi_Reader)(stream_data) + for len(mr.readers) > 0 { + r := mr.readers[0] + n, err = _i64_err(read(r, p)) + if err == .EOF { + ordered_remove(&mr.readers, 0) } - return 0, .EOF - }, + if n > 0 || err != .EOF { + if err == .EOF && len(mr.readers) > 0 { + // Don't return EOF yet, more readers remain + err = nil + } + return + } + } + return 0, .EOF } + multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := context.allocator) -> (r: Reader) { all_readers := make([dynamic]Reader, 0, len(readers), allocator) for w in readers { - if w.stream_vtable == _multi_reader_vtable { - other := (^Multi_Reader)(w.stream_data) + if w.procedure == _multi_reader_proc { + other := (^Multi_Reader)(w.data) append(&all_readers, ..other.readers[:]) } else { append(&all_readers, w) @@ -40,8 +44,8 @@ multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := con mr.readers = all_readers - r.stream_vtable = _multi_reader_vtable - r.stream_data = mr + r.procedure = _multi_reader_proc + r.data = mr return } @@ -55,38 +59,42 @@ Multi_Writer :: struct { } @(private) -_multi_writer_vtable := &Stream_VTable{ - impl_write = proc(s: Stream, p: []byte) -> (n: int, err: Error) { - mw := (^Multi_Writer)(s.stream_data) - for w in mw.writers { - n, err = write(w, p) - if err != nil { - return - } - if n != len(p) { - err = .Short_Write - return - } +_multi_writer_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { + if mode == .Query { + return query_utility({.Write, .Query}) + } else if mode != .Write { + return 0, .Empty + } + mw := (^Multi_Writer)(stream_data) + for w in mw.writers { + n, err = _i64_err(write(w, p)) + if err != nil { + return } + if n != i64(len(p)) { + err = .Short_Write + return + } + } - return len(p), nil - }, + return i64(len(p)), nil } + multi_writer_init :: proc(mw: ^Multi_Writer, writers: ..Writer, allocator := context.allocator) -> (out: Writer) { mw.writers = make([dynamic]Writer, 0, len(writers), allocator) for w in writers { - if w.stream_vtable == _multi_writer_vtable { - other := (^Multi_Writer)(w.stream_data) + if w.procedure == _multi_writer_proc { + other := (^Multi_Writer)(w.data) append(&mw.writers, ..other.writers[:]) } else { append(&mw.writers, w) } } - out.stream_vtable = _multi_writer_vtable - out.stream_data = mw + out.procedure = _multi_writer_proc + out.data = mw return } diff --git a/core/io/util.odin b/core/io/util.odin index cfd7d3608..c77d0be9d 100644 --- a/core/io/util.odin +++ b/core/io/util.odin @@ -292,17 +292,21 @@ Tee_Reader :: struct { } @(private) -_tee_reader_vtable := &Stream_VTable{ - impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) { - t := (^Tee_Reader)(s.stream_data) - n, err = read(t.r, p) +_tee_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { + t := (^Tee_Reader)(stream_data) + #partial switch mode { + case .Read: + n, err = _i64_err(read(t.r, p)) if n > 0 { if wn, werr := write(t.w, p[:n]); werr != nil { - return wn, werr + return i64(wn), werr } } return - }, + case .Query: + return query_utility({.Read, .Query}) + } + return 0, .Empty } // tee_reader_init returns a Reader that writes to 'w' what it reads from 'r' @@ -317,8 +321,8 @@ tee_reader_init :: proc(t: ^Tee_Reader, r: Reader, w: Writer, allocator := conte } tee_reader_to_reader :: proc(t: ^Tee_Reader) -> (r: Reader) { - r.stream_data = t - r.stream_vtable = _tee_reader_vtable + r.data = t + r.procedure = _tee_reader_proc return } @@ -332,9 +336,10 @@ Limited_Reader :: struct { } @(private) -_limited_reader_vtable := &Stream_VTable{ - impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) { - l := (^Limited_Reader)(s.stream_data) +_limited_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { + l := (^Limited_Reader)(stream_data) + #partial switch mode { + case .Read: if l.n <= 0 { return 0, .EOF } @@ -342,10 +347,13 @@ _limited_reader_vtable := &Stream_VTable{ if i64(len(p)) > l.n { p = p[0:l.n] } - n, err = read(l.r, p) + n, err = _i64_err(read(l.r, p)) l.n -= i64(n) return - }, + case .Query: + return query_utility({.Read, .Query}) + } + return 0, .Empty } limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader { @@ -355,8 +363,8 @@ limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader { } limited_reader_to_reader :: proc(l: ^Limited_Reader) -> (r: Reader) { - r.stream_vtable = _limited_reader_vtable - r.stream_data = l + r.procedure = _limited_reader_proc + r.data = l return } @@ -375,15 +383,16 @@ section_reader_init :: proc(s: ^Section_Reader, r: Reader_At, off: i64, n: i64) return } section_reader_to_stream :: proc(s: ^Section_Reader) -> (out: Stream) { - out.stream_data = s - out.stream_vtable = _section_reader_vtable + out.data = s + out.procedure = _section_reader_proc return } @(private) -_section_reader_vtable := &Stream_VTable{ - impl_read = proc(stream: Stream, p: []byte) -> (n: int, err: Error) { - s := (^Section_Reader)(stream.stream_data) +_section_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { + s := (^Section_Reader)(stream_data) + #partial switch mode { + case .Read: if s.off >= s.limit { return 0, .EOF } @@ -391,13 +400,11 @@ _section_reader_vtable := &Stream_VTable{ if max := s.limit - s.off; i64(len(p)) > max { p = p[0:max] } - n, err = read_at(s.r, p, s.off) + n, err = _i64_err(read_at(s.r, p, s.off)) s.off += i64(n) return - }, - impl_read_at = proc(stream: Stream, p: []byte, off: i64) -> (n: int, err: Error) { - s := (^Section_Reader)(stream.stream_data) - p, off := p, off + case .Read_At: + p, off := p, offset if off < 0 || off >= s.limit - s.base { return 0, .EOF @@ -405,17 +412,15 @@ _section_reader_vtable := &Stream_VTable{ off += s.base if max := s.limit - off; i64(len(p)) > max { p = p[0:max] - n, err = read_at(s.r, p, off) + n, err = _i64_err(read_at(s.r, p, off)) if err == nil { err = .EOF } return } - return read_at(s.r, p, off) - }, - impl_seek = proc(stream: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { - s := (^Section_Reader)(stream.stream_data) + return _i64_err(read_at(s.r, p, off)) + case .Seek: offset := offset switch whence { case: @@ -433,10 +438,12 @@ _section_reader_vtable := &Stream_VTable{ s.off = offset n = offset - s.base return - }, - impl_size = proc(stream: Stream) -> i64 { - s := (^Section_Reader)(stream.stream_data) - return s.limit - s.base - }, -} + case .Size: + n = s.limit - s.base + return + case .Query: + return query_utility({.Read, .Read_At, .Seek, .Size, .Query}) + } + return 0, nil +} diff --git a/core/os/os2/errors_windows.odin b/core/os/os2/errors_windows.odin index 27c16e72e..6500e7ccc 100644 --- a/core/os/os2/errors_windows.odin +++ b/core/os/os2/errors_windows.odin @@ -37,14 +37,18 @@ _get_platform_error :: proc() -> Error { case win32.ERROR_NOT_SUPPORTED: return .Unsupported + case win32.ERROR_HANDLE_EOF: + return .EOF + + case win32.ERROR_INVALID_HANDLE: + return .Invalid_File + case win32.ERROR_BAD_ARGUMENTS, win32.ERROR_INVALID_PARAMETER, win32.ERROR_NOT_ENOUGH_MEMORY, - win32.ERROR_INVALID_HANDLE, win32.ERROR_NO_MORE_FILES, win32.ERROR_LOCK_VIOLATION, - win32.ERROR_HANDLE_EOF, win32.ERROR_BROKEN_PIPE, win32.ERROR_CALL_NOT_IMPLEMENTED, win32.ERROR_INSUFFICIENT_BUFFER, diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index eb6d9e366..da822374a 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -8,12 +8,6 @@ File :: struct { impl: _File, } -Seek_From :: enum { - Start = 0, // seek relative to the origin of the file - Current = 1, // seek relative to the current offset - End = 2, // seek relative to the end -} - File_Mode :: distinct u32 File_Mode_Dir :: File_Mode(1<<16) File_Mode_Named_Pipe :: File_Mode(1<<17) @@ -72,54 +66,68 @@ fd :: proc(f: ^File) -> uintptr { return _fd(f) } - -close :: proc(f: ^File) -> Error { - return _close(f) -} - name :: proc(f: ^File) -> string { return _name(f) } -seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { - return _seek(f, offset, whence) +close :: proc(f: ^File) -> Error { + if f != nil { + return io.close(f.impl.stream) + } + return nil +} + +seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { + if f != nil { + return io.seek(f.impl.stream, offset, whence) + } + return 0, .Invalid_File } read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return _read(f, p) + if f != nil { + return io.read(f.impl.stream, p) + } + return 0, .Invalid_File } read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { - return _read_at(f, p, offset) -} - -read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { - return _read_from(f, r) + if f != nil { + return io.read_at(f.impl.stream, p, offset) + } + return 0, .Invalid_File } write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return _write(f, p) + if f != nil { + return io.write(f.impl.stream, p) + } + return 0, .Invalid_File } write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { - return _write_at(f, p, offset) -} - -write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { - return _write_to(f, w) + if f != nil { + return io.write_at(f.impl.stream, p, offset) + } + return 0, .Invalid_File } file_size :: proc(f: ^File) -> (n: i64, err: Error) { - return _file_size(f) -} - - -sync :: proc(f: ^File) -> Error { - return _sync(f) + if f != nil { + return io.size(f.impl.stream) + } + return 0, .Invalid_File } flush :: proc(f: ^File) -> Error { - return _flush(f) + if f != nil { + return io.flush(f.impl.stream) + } + return nil +} + +sync :: proc(f: ^File) -> Error { + return _sync(f) } truncate :: proc(f: ^File, size: i64) -> Error { diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 890bbfc43..ddd827bce 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -33,6 +33,8 @@ _File :: struct { name: string, fd: int, allocator: runtime.Allocator, + + stream: io.Stream, } _file_allocator :: proc() -> runtime.Allocator { @@ -73,6 +75,10 @@ _new_file :: proc(fd: uintptr, _: string) -> ^File { file.impl.fd = int(fd) file.impl.allocator = _file_allocator() file.impl.name = _get_full_path(file.impl.fd, file.impl.allocator) + file.impl.stream = { + data = file, + procedure = _file_stream_proc, + } return file } @@ -102,7 +108,7 @@ _name :: proc(f: ^File) -> string { return f.impl.name if f != nil else "" } -_seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { +_seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { res := unix.sys_lseek(f.impl.fd, offset, int(whence)) if res < 0 { return -1, _get_platform_error(int(res)) @@ -110,18 +116,18 @@ _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error return res, nil } -_read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { +_read :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n = unix.sys_read(f.impl.fd, &p[0], len(p)) + n := unix.sys_read(f.impl.fd, &p[0], len(p)) if n < 0 { return -1, _get_platform_error(n) } - return n, nil + return i64(n), nil } -_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { if offset < 0 { return 0, .Invalid_Offset } @@ -132,30 +138,25 @@ _read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { if m < 0 { return -1, _get_platform_error(m) } - n += m + n += i64(m) b = b[m:] offset += i64(m) } return } -_read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { - //TODO - return -} - -_write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { +_write :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n = unix.sys_write(f.impl.fd, &p[0], uint(len(p))) + n := unix.sys_write(f.impl.fd, &p[0], uint(len(p))) if n < 0 { return -1, _get_platform_error(n) } - return int(n), nil + return i64(n), nil } -_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { if offset < 0 { return 0, .Invalid_Offset } @@ -166,18 +167,13 @@ _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { if m < 0 { return -1, _get_platform_error(m) } - n += m + n += i64(m) b = b[m:] offset += i64(m) } return } -_write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { - //TODO - return -} - _file_size :: proc(f: ^File) -> (n: i64, err: Error) { s: _Stat = --- res := unix.sys_fstat(f.impl.fd, &s) @@ -366,3 +362,49 @@ _is_dir_fd :: proc(fd: int) -> bool { _temp_name_to_cstring :: proc(name: string) -> (cname: cstring) { return strings.clone_to_cstring(name, context.temp_allocator) } + + +@(private="package") +_file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + f := (^File)(stream_data) + ferr: Error + i: int + switch mode { + case .Read: + n, ferr = _read(f, p) + err = error_to_io_error(ferr) + return + case .Read_At: + n, ferr = _read_at(f, p, offset) + err = error_to_io_error(ferr) + return + case .Write: + n, ferr = _write(f, p) + err = error_to_io_error(ferr) + return + case .Write_At: + n, ferr = _write_at(f, p, offset) + err = error_to_io_error(ferr) + return + case .Seek: + n, ferr = _seek(f, offset, whence) + err = error_to_io_error(ferr) + return + case .Size: + n, ferr = _file_size(f) + err = error_to_io_error(ferr) + return + case .Flush: + ferr = _flush(f) + err = error_to_io_error(ferr) + return + case .Close, .Destroy: + ferr = _close(f) + err = error_to_io_error(ferr) + return + case .Query: + return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Flush, .Close, .Destroy, .Query}) + } + return 0, .Empty +} + diff --git a/core/os/os2/file_stream.odin b/core/os/os2/file_stream.odin index 7edbd68fa..da1e3344f 100644 --- a/core/os/os2/file_stream.odin +++ b/core/os/os2/file_stream.odin @@ -3,17 +3,15 @@ package os2 import "core:io" to_stream :: proc(f: ^File) -> (s: io.Stream) { - s.stream_data = f - s.stream_vtable = &_file_stream_vtable + if f != nil { + assert(f.impl.stream.procedure != nil) + s = f.impl.stream + } return } -to_writer :: proc(f: ^File) -> (s: io.Writer) { - return {to_stream(f)} -} -to_reader :: proc(f: ^File) -> (s: io.Reader) { - return {to_stream(f)} -} +to_writer :: to_stream +to_reader :: to_stream @(private) @@ -23,71 +21,3 @@ error_to_io_error :: proc(ferr: Error) -> io.Error { } return ferr.(io.Error) or_else .Unknown } - - -@(private) -_file_stream_vtable := io.Stream_VTable{ - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = read(f, p) - err = error_to_io_error(ferr) - return - }, - impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = read_at(f, p, offset) - err = error_to_io_error(ferr) - return - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = write_to(f, w) - err = error_to_io_error(ferr) - return - }, - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = write(f, p) - err = error_to_io_error(ferr) - return - }, - impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = write_at(f, p, offset) - err = error_to_io_error(ferr) - return - }, - impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) { - f := (^File)(s.stream_data) - ferr: Error - n, ferr = read_from(f, r) - err = error_to_io_error(ferr) - return - }, - impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { - f := (^File)(s.stream_data) - n, ferr := seek(f, offset, Seek_From(whence)) - err := error_to_io_error(ferr) - return n, err - }, - impl_size = proc(s: io.Stream) -> i64 { - f := (^File)(s.stream_data) - sz, _ := file_size(f) - return sz - }, - impl_flush = proc(s: io.Stream) -> io.Error { - f := (^File)(s.stream_data) - ferr := flush(f) - return error_to_io_error(ferr) - }, - impl_close = proc(s: io.Stream) -> io.Error { - f := (^File)(s.stream_data) - ferr := close(f) - return error_to_io_error(ferr) - }, -} diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index bc1530dc7..600ecde21 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -38,6 +38,8 @@ _File :: struct { wname: win32.wstring, kind: _File_Kind, + stream: io.Stream, + allocator: runtime.Allocator, rw_mutex: sync.RW_Mutex, // read write calls @@ -144,6 +146,11 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File { } f.impl.kind = kind + f.impl.stream = { + data = f, + procedure = _file_stream_proc, + } + return f } @@ -181,7 +188,7 @@ _name :: proc(f: ^File) -> string { return f.impl.name if f != nil else "" } -_seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { +_seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { handle := _handle(f) if handle == win32.INVALID_HANDLE { return 0, .Invalid_File @@ -208,7 +215,7 @@ _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error return i64(hi)<<32 + i64(dw_ptr), nil } -_read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { +_read :: proc(f: ^File, p: []byte) -> (n: i64, err: Error) { read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Error) { if len(b) == 0 { return 0, nil @@ -274,7 +281,7 @@ _read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { n, err := read_console(handle, p[total_read:][:to_read]) total_read += n if err != nil { - return int(total_read), err + return i64(total_read), err } } else { ok = win32.ReadFile(handle, &p[total_read], to_read, &single_read_length, nil) @@ -287,11 +294,11 @@ _read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { } } - return int(total_read), err + return i64(total_read), err } -_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { - pread :: proc(f: ^File, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { + pread :: proc(f: ^File, data: []byte, offset: i64) -> (n: i64, err: Error) { buf := data if len(buf) > MAX_RW { buf = buf[:MAX_RW] @@ -313,7 +320,7 @@ _read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { err = _get_platform_error() done = 0 } - n = int(done) + n = i64(done) return } @@ -329,12 +336,7 @@ _read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return } -_read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { - // TODO(bill) - return -} - -_write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { +_write :: proc(f: ^File, p: []byte) -> (n: i64, err: Error) { if len(p) == 0 { return } @@ -352,17 +354,17 @@ _write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { e := win32.WriteFile(handle, &p[total_write], to_write, &single_write_length, nil) if single_write_length <= 0 || !e { - n = int(total_write) + n = i64(total_write) err = _get_platform_error() return } total_write += i64(single_write_length) } - return int(total_write), nil + return i64(total_write), nil } -_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { - pwrite :: proc(f: ^File, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { + pwrite :: proc(f: ^File, data: []byte, offset: i64) -> (n: i64, err: Error) { buf := data if len(buf) > MAX_RW { buf = buf[:MAX_RW] @@ -382,7 +384,7 @@ _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { err = _get_platform_error() done = 0 } - n = int(done) + n = i64(done) return } @@ -397,11 +399,6 @@ _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return } -_write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { - // TODO(bill) - return -} - _file_size :: proc(f: ^File) -> (n: i64, err: Error) { length: win32.LARGE_INTEGER handle := _handle(f) @@ -727,3 +724,51 @@ _is_dir :: proc(path: string) -> bool { } return false } + + +@(private="package") +_file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + f := (^File)(stream_data) + ferr: Error + i: int + switch mode { + case .Read: + n, ferr = _read(f, p) + err = error_to_io_error(ferr) + return + case .Read_At: + n, ferr = _read_at(f, p, offset) + err = error_to_io_error(ferr) + return + case .Write: + n, ferr = _write(f, p) + err = error_to_io_error(ferr) + return + case .Write_At: + n, ferr = _write_at(f, p, offset) + err = error_to_io_error(ferr) + return + case .Seek: + n, ferr = _seek(f, offset, whence) + err = error_to_io_error(ferr) + return + case .Size: + n, ferr = _file_size(f) + err = error_to_io_error(ferr) + return + case .Flush: + ferr = _flush(f) + err = error_to_io_error(ferr) + return + case .Close: + ferr = _close(f) + err = error_to_io_error(ferr) + return + case .Query: + return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Flush, .Close, .Query}) + case .Destroy: + return 0, .Empty + } + return 0, .Empty +} + diff --git a/core/os/stream.odin b/core/os/stream.odin index 9506ed3a3..2b4c83663 100644 --- a/core/os/stream.odin +++ b/core/os/stream.odin @@ -4,66 +4,60 @@ import "core:io" stream_from_handle :: proc(fd: Handle) -> io.Stream { s: io.Stream - s.stream_data = rawptr(uintptr(fd)) - s.stream_vtable = &_file_stream_vtable + s.data = rawptr(uintptr(fd)) + s.procedure = _file_stream_proc return s } @(private) -_file_stream_vtable := io.Stream_VTable{ - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) - os_err: Errno - n, os_err = read(fd, p) - return - }, - impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == .Windows || ODIN_OS == .WASI { - fd := Handle(uintptr(s.stream_data)) - os_err: Errno - n, os_err = read_at(fd, p, offset) - } - return - }, - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) - os_err: Errno - n, os_err = write(fd, p) - return - }, - impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == .Windows || ODIN_OS == .WASI { - fd := Handle(uintptr(s.stream_data)) - os_err: Errno - n, os_err = write_at(fd, p, offset) - _ = os_err - } - return - }, - impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { - fd := Handle(uintptr(s.stream_data)) - n, os_err := seek(fd, offset, int(whence)) - _ = os_err - return n, nil - }, - impl_size = proc(s: io.Stream) -> i64 { - fd := Handle(uintptr(s.stream_data)) - sz, _ := file_size(fd) - return sz - }, - impl_flush = proc(s: io.Stream) -> io.Error { +_file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + fd := Handle(uintptr(stream_data)) + n_int: int + os_err: Errno + switch mode { + case .Close: + close(fd) + case .Flush: when ODIN_OS == .Windows { - fd := Handle(uintptr(s.stream_data)) flush(fd) } else { // TOOD(bill): other operating systems } - return nil - }, - impl_close = proc(s: io.Stream) -> io.Error { - fd := Handle(uintptr(s.stream_data)) - close(fd) - return nil - }, + case .Read: + n_int, os_err = read(fd, p) + n = i64(n_int) + if os_err != 0 { + err = .Unknown + } + case .Read_At: + when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD) { + n_int, os_err = read_at(fd, p, offset) + n = i64(n_int) + } + case .Write: + n_int, os_err = write(fd, p) + n = i64(n_int) + case .Write_At: + when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD) { + n_int, os_err = write_at(fd, p, offset) + n = i64(n_int) + } + case .Seek: + n, os_err = seek(fd, offset, int(whence)) + case .Size: + n, os_err = file_size(fd) + case .Destroy: + err = .Empty + case .Query: + when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD { + return io.query_utility({.Close, .Flush, .Read, .Write, .Seek, .Size, .Query}) + } else { + return io.query_utility({.Close, .Flush, .Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Query}) + } + } + if err == nil && os_err != 0 { + err = .Unknown + } + return } diff --git a/core/strings/builder.odin b/core/strings/builder.odin index edde4b297..28c56f6f9 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -164,36 +164,27 @@ builder_init :: proc{ builder_init_len_cap, } @(private) -_builder_stream_vtable_obj := io.Stream_VTable{ - impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - b := (^Builder)(s.stream_data) - n = write_bytes(b, p) - if n < len(p) { +_builder_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + b := (^Builder)(stream_data) + #partial switch mode { + case .Write: + n = i64(write_bytes(b, p)) + if n < i64(len(p)) { err = .EOF } return - }, - impl_write_byte = proc(s: io.Stream, c: byte) -> (err: io.Error) { - b := (^Builder)(s.stream_data) - n := write_byte(b, c) - if n == 0 { - err = .EOF - } + case .Size: + n = i64(len(b.buf)) return - }, - impl_size = proc(s: io.Stream) -> i64 { - b := (^Builder)(s.stream_data) - return i64(len(b.buf)) - }, - impl_destroy = proc(s: io.Stream) -> io.Error { - b := (^Builder)(s.stream_data) + case .Destroy: builder_destroy(b) - return .None - }, + return + case .Query: + return io.query_utility({.Write, .Size, .Destroy, .Query}) + } + return 0, .Empty } -// NOTE(dweiler): Work around a miscompilation bug on Linux still. -@(private) -_builder_stream_vtable := &_builder_stream_vtable_obj + /* Returns an io.Stream from a Builder @@ -204,7 +195,7 @@ Returns: - res: the io.Stream */ to_stream :: proc(b: ^Builder) -> (res: io.Stream) { - return io.Stream{stream_vtable=_builder_stream_vtable, stream_data=b} + return io.Stream{procedure=_builder_stream_proc, data=b} } /* Returns an io.Writer from a Builder diff --git a/core/strings/reader.odin b/core/strings/reader.odin index 081e59b4b..bb49bf917 100644 --- a/core/strings/reader.odin +++ b/core/strings/reader.odin @@ -35,8 +35,8 @@ Returns: - s: An io.Stream for the given Reader */ reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) { - s.stream_data = r - s.stream_vtable = &_reader_vtable + s.data = r + s.procedure = _reader_proc return } /* @@ -294,41 +294,21 @@ This VTable is used by the Reader struct to provide its functionality as an `io.Stream`. */ @(private) -_reader_vtable := io.Stream_VTable{ - impl_size = proc(s: io.Stream) -> i64 { - r := (^Reader)(s.stream_data) - return reader_size(r) - }, - impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read(r, p) - }, - impl_read_at = proc(s: io.Stream, p: []byte, off: i64) -> (n: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_at(r, p, off) - }, - impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_byte(r) - }, - impl_unread_byte = proc(s: io.Stream) -> io.Error { - r := (^Reader)(s.stream_data) - return reader_unread_byte(r) - }, - impl_read_rune = proc(s: io.Stream) -> (ch: rune, size: int, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_read_rune(r) - }, - impl_unread_rune = proc(s: io.Stream) -> io.Error { - r := (^Reader)(s.stream_data) - return reader_unread_rune(r) - }, - impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { - r := (^Reader)(s.stream_data) - return reader_seek(r, offset, whence) - }, - impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - r := (^Reader)(s.stream_data) - return reader_write_to(r, w) - }, +_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) { + r := (^Reader)(stream_data) + #partial switch mode { + case .Size: + n = reader_size(r) + return + case .Read: + return io._i64_err(reader_read(r, p)) + case .Read_At: + return io._i64_err(reader_read_at(r, p, offset)) + case .Seek: + n, err = reader_seek(r, offset, whence) + return + case .Query: + return io.query_utility({.Size, .Read, .Read_At, .Seek, .Query}) + } + return 0, .Empty } diff --git a/vendor/botan/blake2b/blake2b.odin b/vendor/botan/blake2b/blake2b.odin index 18fd89bd8..6cc828caf 100644 --- a/vendor/botan/blake2b/blake2b.odin +++ b/vendor/botan/blake2b/blake2b.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/gost/gost.odin b/vendor/botan/gost/gost.odin index bccc4d463..5b3db31fe 100644 --- a/vendor/botan/gost/gost.odin +++ b/vendor/botan/gost/gost.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/keccak/keccak.odin b/vendor/botan/keccak/keccak.odin index 4c82edc92..c08eaf598 100644 --- a/vendor/botan/keccak/keccak.odin +++ b/vendor/botan/keccak/keccak.odin @@ -69,7 +69,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/md4/md4.odin b/vendor/botan/md4/md4.odin index ddb7d5940..02c33dde9 100644 --- a/vendor/botan/md4/md4.odin +++ b/vendor/botan/md4/md4.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/md5/md5.odin b/vendor/botan/md5/md5.odin index 9ea489669..9aaf96d27 100644 --- a/vendor/botan/md5/md5.odin +++ b/vendor/botan/md5/md5.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/ripemd/ripemd.odin b/vendor/botan/ripemd/ripemd.odin index 33f0ba692..ddb549350 100644 --- a/vendor/botan/ripemd/ripemd.odin +++ b/vendor/botan/ripemd/ripemd.odin @@ -69,7 +69,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/sha1/sha1.odin b/vendor/botan/sha1/sha1.odin index 96520f09e..c39a41d0a 100644 --- a/vendor/botan/sha1/sha1.odin +++ b/vendor/botan/sha1/sha1.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/sha2/sha2.odin b/vendor/botan/sha2/sha2.odin index d583298ee..4ce001a75 100644 --- a/vendor/botan/sha2/sha2.odin +++ b/vendor/botan/sha2/sha2.odin @@ -72,7 +72,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -151,7 +151,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -230,7 +230,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -309,7 +309,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/sha3/sha3.odin b/vendor/botan/sha3/sha3.odin index 5f82be49c..5dcb008ce 100644 --- a/vendor/botan/sha3/sha3.odin +++ b/vendor/botan/sha3/sha3.odin @@ -72,7 +72,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -151,7 +151,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -230,7 +230,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -309,7 +309,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/shake/shake.odin b/vendor/botan/shake/shake.odin index b973fee24..af577f316 100644 --- a/vendor/botan/shake/shake.odin +++ b/vendor/botan/shake/shake.odin @@ -70,7 +70,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/skein512/skein512.odin b/vendor/botan/skein512/skein512.odin index 41ffaefff..47529bc44 100644 --- a/vendor/botan/skein512/skein512.odin +++ b/vendor/botan/skein512/skein512.odin @@ -72,7 +72,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -151,7 +151,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -230,7 +230,7 @@ hash_stream_slice :: proc(s: io.Stream, bit_size: int, allocator := context.allo defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/sm3/sm3.odin b/vendor/botan/sm3/sm3.odin index 52fe9a488..dd6da9e63 100644 --- a/vendor/botan/sm3/sm3.odin +++ b/vendor/botan/sm3/sm3.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/streebog/streebog.odin b/vendor/botan/streebog/streebog.odin index fdc07923f..07c39684a 100644 --- a/vendor/botan/streebog/streebog.odin +++ b/vendor/botan/streebog/streebog.odin @@ -70,7 +70,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -149,7 +149,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/tiger/tiger.odin b/vendor/botan/tiger/tiger.odin index 3d7e064d0..960d4694b 100644 --- a/vendor/botan/tiger/tiger.odin +++ b/vendor/botan/tiger/tiger.odin @@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } @@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) } diff --git a/vendor/botan/whirlpool/whirlpool.odin b/vendor/botan/whirlpool/whirlpool.odin index c32ff20c0..76d4d25d4 100644 --- a/vendor/botan/whirlpool/whirlpool.odin +++ b/vendor/botan/whirlpool/whirlpool.odin @@ -69,7 +69,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { defer delete(buf) i := 1 for i > 0 { - i, _ = s->impl_read(buf) + i, _ = io.read(s, buf) if i > 0 { botan.hash_update(ctx, len(buf) == 0 ? nil : &buf[0], uint(i)) }