aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2023-06-23 12:12:17 +0100
committerGitHub <noreply@github.com>2023-06-23 12:12:17 +0100
commit19ea0906332e6185cd0eefe873179b9058ccd725 (patch)
tree807540705d576d1153c67219f06b6c6fe785b461 /core
parent9841b11a5423e2cba67c19fbd06e28732d36109c (diff)
parenta78d6fe0b39d57f002a397d54bb506df7a3d2f1b (diff)
Merge pull request #2584 from odin-lang/new-io
New and Improved `io.Stream` interface
Diffstat (limited to 'core')
-rw-r--r--core/bufio/read_writer.odin66
-rw-r--r--core/bufio/reader.odin58
-rw-r--r--core/bufio/writer.odin59
-rw-r--r--core/bytes/buffer.odin82
-rw-r--r--core/bytes/reader.odin59
-rw-r--r--core/compress/common.odin5
-rw-r--r--core/crypto/blake/blake.odin8
-rw-r--r--core/crypto/blake2b/blake2b.odin2
-rw-r--r--core/crypto/blake2s/blake2s.odin2
-rw-r--r--core/crypto/gost/gost.odin2
-rw-r--r--core/crypto/groestl/groestl.odin8
-rw-r--r--core/crypto/haval/haval.odin30
-rw-r--r--core/crypto/jh/jh.odin8
-rw-r--r--core/crypto/keccak/keccak.odin8
-rw-r--r--core/crypto/md2/md2.odin2
-rw-r--r--core/crypto/md4/md4.odin2
-rw-r--r--core/crypto/md5/md5.odin2
-rw-r--r--core/crypto/ripemd/ripemd.odin8
-rw-r--r--core/crypto/sha1/sha1.odin2
-rw-r--r--core/crypto/sha2/sha2.odin8
-rw-r--r--core/crypto/sha3/sha3.odin8
-rw-r--r--core/crypto/shake/shake.odin4
-rw-r--r--core/crypto/sm3/sm3.odin2
-rw-r--r--core/crypto/streebog/streebog.odin4
-rw-r--r--core/crypto/tiger/tiger.odin6
-rw-r--r--core/crypto/tiger2/tiger2.odin6
-rw-r--r--core/crypto/whirlpool/whirlpool.odin2
-rw-r--r--core/fmt/fmt_os.odin10
-rw-r--r--core/io/conv.odin104
-rw-r--r--core/io/io.odin440
-rw-r--r--core/io/multi.odin86
-rw-r--r--core/io/util.odin79
-rw-r--r--core/os/os2/errors_windows.odin8
-rw-r--r--core/os/os2/file.odin68
-rw-r--r--core/os/os2/file_linux.odin84
-rw-r--r--core/os/os2/file_stream.odin82
-rw-r--r--core/os/os2/file_windows.odin91
-rw-r--r--core/os/stream.odin98
-rw-r--r--core/strings/builder.odin41
-rw-r--r--core/strings/reader.odin58
40 files changed, 693 insertions, 1009 deletions
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 :: struct {
- using stream_vtable: ^Stream_VTable,
- stream_data: rawptr,
+Stream_Mode :: enum {
+ Close,
+ Flush,
+ Read,
+ Read_At,
+ Write,
+ Write_At,
+ Seek,
+ Size,
+ Destroy,
+ Query, // query what modes are available
}
-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,
+Stream_Mode_Set :: distinct bit_set[Stream_Mode; i64]
- 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,
+Stream_Proc :: #type proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
- impl_unread_byte: Unread_Byte_Proc,
- impl_unread_rune: Unread_Rune_Proc,
-
- impl_destroy: Destroy_Proc,
+Stream :: struct {
+ 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 :: struct {using stream: Stream}
-Read_Closer :: struct {using stream: Stream}
-Read_Write_Closer :: struct {using stream: Stream}
-Read_Write_Seeker :: struct {using stream: Stream}
+Read_Writer :: Stream
+Read_Closer :: Stream
+Read_Write_Closer :: Stream
+Read_Write_Seeker :: 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}
+Write_Closer :: Stream
+Write_Seeker :: Stream
+Write_Flusher :: Stream
+Write_Flush_Closer :: 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
+}
+
+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 .Empty
+ 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
- }
- 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
+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
}
-
- 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)
+ }
+ 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
- },
+ }
+ 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,56 +66,70 @@ 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
}
-read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) {
- return _read(f, p)
+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_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) {
- return _read_at(f, p, offset)
+read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) {
+ if f != nil {
+ return io.read(f.impl.stream, p)
+ }
+ return 0, .Invalid_File
}
-read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) {
- return _read_from(f, r)
+read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) {
+ 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)
+ if f != nil {
+ return io.size(f.impl.stream)
+ }
+ return 0, .Invalid_File
}
+flush :: proc(f: ^File) -> Error {
+ if f != nil {
+ return io.flush(f.impl.stream)
+ }
+ return nil
+}
sync :: proc(f: ^File) -> Error {
return _sync(f)
}
-flush :: proc(f: ^File) -> Error {
- return _flush(f)
-}
-
truncate :: proc(f: ^File, size: i64) -> Error {
return _truncate(f, size)
}
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
}