From 0cf3ae93c052e33984cc73a557a8a8cdd411ad0e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 2 Dec 2020 23:39:33 +0000 Subject: [PATCH] Add `os.stream_from_handle`; fix `io.close` --- core/io/io.odin | 5 ++-- core/os/stream.odin | 62 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 core/os/stream.odin diff --git a/core/io/io.odin b/core/io/io.odin index 7aca6e25f..47363bd28 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -113,11 +113,12 @@ Rune_Scanner :: struct {using stream: Stream}; destroy :: proc(s: Stream) -> Error { + close_err := close({s}); if s.stream_vtable != nil && s.impl_destroy != nil { return s->impl_destroy(); } // Instead of .Empty, .None is fine in this case - return .None; + return close_err; } read :: proc(s: Reader, p: []byte) -> (n: int, err: Error) { @@ -141,7 +142,7 @@ seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) return 0, .Empty; } -close :: proc(s: Closer, p: []byte) -> Error { +close :: proc(s: Closer) -> Error { if s.stream_vtable != nil && s.impl_close != nil { return s->impl_close(); } diff --git a/core/os/stream.odin b/core/os/stream.odin new file mode 100644 index 000000000..c82f38107 --- /dev/null +++ b/core/os/stream.odin @@ -0,0 +1,62 @@ +package os + +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; + return s; +} + + +_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) { + 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) { + fd := Handle(uintptr(s.stream_data)); + os_err: Errno; + n, os_err = write_at(fd, p, offset); + 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)); + 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 { + fd := Handle(uintptr(s.stream_data)); + when ODIN_OS == "windows" { + 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; + }, +};