stream.ha (1691B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use errors; 5 6 // A stream is a pointer to a [[vtable]] which allows for user-defined I/O 7 // abstractions to implement some subset of read, write, seek, close, and other 8 // I/O functionality in userspace. Embed to create a custom stream type: 9 // 10 // export type my_stream = struct { 11 // vtable: io::stream, 12 // fd: int, 13 // }; 14 // 15 // const my_vtable: io::vtable = io::vtable { 16 // reader = &my_stream_read, 17 // writer = &my_stream_write, 18 // closer = null, 19 // ... 20 // }; 21 // 22 // export fn open(path: str) my_stream = { 23 // let fd = // ... 24 // return my_stream { 25 // vtable = &my_vtable, 26 // fd = fd, 27 // ... 28 // }); 29 // }; 30 // 31 // let stream = open("example"); 32 // io::read(&stream, buf)!; 33 export type stream = *vtable; 34 35 // The vtable type defines a set of virtual functions for a [[stream]]. 36 export type vtable = struct { 37 reader: nullable *reader, 38 writer: nullable *writer, 39 closer: nullable *closer, 40 seeker: nullable *seeker, 41 copier: nullable *copier, 42 }; 43 44 fn st_read(s: *stream, buf: []u8) (size | EOF | error) = { 45 match (s.reader) { 46 case null => 47 return errors::unsupported; 48 case let r: *reader => 49 return r(s, buf); 50 }; 51 }; 52 53 fn st_write(s: *stream, buf: const []u8) (size | error) = { 54 match (s.writer) { 55 case null => 56 return errors::unsupported; 57 case let w: *writer => 58 return w(s, buf); 59 }; 60 }; 61 62 fn st_close(s: *stream) (void | error) = { 63 match (s.closer) { 64 case null => void; 65 case let c: *closer => 66 c(s)?; 67 }; 68 }; 69 70 fn st_seek(s: *stream, off: off, w: whence) (off | error) = { 71 match (s.seeker) { 72 case null => 73 return errors::unsupported; 74 case let sk: *seeker => 75 return sk(s, off, w); 76 }; 77 };