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