Browse Source

Add `os.stream_from_handle`; fix `io.close`

gingerBill 4 years ago
parent
commit
0cf3ae93c0
2 changed files with 65 additions and 2 deletions
  1. 3 2
      core/io/io.odin
  2. 62 0
      core/os/stream.odin

+ 3 - 2
core/io/io.odin

@@ -113,11 +113,12 @@ Rune_Scanner       :: struct {using stream: Stream};
 
 
 
 
 destroy :: proc(s: Stream) -> Error {
 destroy :: proc(s: Stream) -> Error {
+	close_err := close({s});
 	if s.stream_vtable != nil && s.impl_destroy != nil {
 	if s.stream_vtable != nil && s.impl_destroy != nil {
 		return s->impl_destroy();
 		return s->impl_destroy();
 	}
 	}
 	// Instead of .Empty, .None is fine in this case
 	// Instead of .Empty, .None is fine in this case
-	return .None;
+	return close_err;
 }
 }
 
 
 read :: proc(s: Reader, p: []byte) -> (n: int, err: Error) {
 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;
 	return 0, .Empty;
 }
 }
 
 
-close :: proc(s: Closer, p: []byte) -> Error {
+close :: proc(s: Closer) -> Error {
 	if s.stream_vtable != nil && s.impl_close != nil {
 	if s.stream_vtable != nil && s.impl_close != nil {
 		return s->impl_close();
 		return s->impl_close();
 	}
 	}

+ 62 - 0
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;
+	},
+};