From 145a7a24e8710a428f48db64c23544ac813a6814 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 8 Jun 2023 16:55:01 +0100 Subject: [PATCH] Use `io.Stream` as the internal interface for `os2.File` --- core/os/os2/file.odin | 42 +++++++-------------- core/os/os2/file_linux.odin | 66 +++++++++++++++++++++++++++------ core/os/os2/file_stream.odin | 58 ++--------------------------- core/os/os2/file_windows.odin | 69 +++++++++++++++++++++++++++++------ 4 files changed, 131 insertions(+), 104 deletions(-) diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index eb6d9e366..6c1cef89f 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -5,13 +5,8 @@ import "core:time" import "core:runtime" 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 + impl: _File, + stream: io.Stream, } File_Mode :: distinct u32 @@ -72,45 +67,36 @@ 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 { + return io.close(f.stream) +} + +seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { + return io.seek(f.stream, offset, whence) } read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return _read(f, p) + return io.read(f.stream, p) } 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) + return io.read_at(f.stream, p, offset) } write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return _write(f, p) + return io.write(f.stream, p) } 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) + return io.write_at(f.stream, p, offset) } file_size :: proc(f: ^File) -> (n: i64, err: Error) { - return _file_size(f) + return io.size(f.stream) } @@ -119,7 +105,7 @@ sync :: proc(f: ^File) -> Error { } flush :: proc(f: ^File) -> Error { - return _flush(f) + return io.flush(f.stream) } 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..a43c1aadf 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -73,6 +73,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.stream = { + data = file, + procedure = _file_stream_proc, + } return file } @@ -102,7 +106,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)) @@ -139,11 +143,6 @@ _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 - return -} - _write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { if len(p) == 0 { return 0, nil @@ -173,11 +172,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 - return -} - _file_size :: proc(f: ^File) -> (n: i64, err: Error) { s: _Stat = --- res := unix.sys_fstat(f.impl.fd, &s) @@ -366,3 +360,53 @@ _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: + i, ferr = _read(f, p) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Read_At: + i, ferr = _read_at(f, p, offset) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Write: + i, ferr = _write(f, p) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Write_At: + i, ferr = _write_at(f, p, offset) + n = i64(i) + 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 91cab3d1c..84176928d 100644 --- a/core/os/os2/file_stream.odin +++ b/core/os/os2/file_stream.odin @@ -3,8 +3,10 @@ package os2 import "core:io" to_stream :: proc(f: ^File) -> (s: io.Stream) { - s.data = f - s.procedure = _file_stream_proc + if f != nil { + assert(f.stream.procedure != nil) + s = f.stream + } return } @@ -19,55 +21,3 @@ error_to_io_error :: proc(ferr: Error) -> io.Error { } return ferr.(io.Error) or_else .Unknown } - - -@(private) -_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: - i, ferr = read(f, p) - n = i64(i) - err = error_to_io_error(ferr) - return - case .Read_At: - i, ferr = read_at(f, p, offset) - n = i64(i) - err = error_to_io_error(ferr) - return - case .Write: - i, ferr = write(f, p) - n = i64(i) - err = error_to_io_error(ferr) - return - case .Write_At: - i, ferr = write_at(f, p, offset) - n = i64(i) - err = error_to_io_error(ferr) - return - case .Seek: - n, ferr = seek(f, offset, Seek_From(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/os2/file_windows.odin b/core/os/os2/file_windows.odin index e4ae4856a..50938d92a 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -144,6 +144,11 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File { } f.impl.kind = kind + f.stream = { + data = f, + procedure = _file_stream_proc, + } + return f } @@ -181,7 +186,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 @@ -329,11 +334,6 @@ _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) { if len(p) == 0 { return @@ -397,11 +397,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 +722,55 @@ _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: + i, ferr = _read(f, p) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Read_At: + i, ferr = _read_at(f, p, offset) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Write: + i, ferr = _write(f, p) + n = i64(i) + err = error_to_io_error(ferr) + return + case .Write_At: + i, ferr = _write_at(f, p, offset) + n = i64(i) + 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 +} +