commit 7ce2904d1ff1f84462dd4622f8f3fc8d1d28ae03
parent 53081a0b2e5c289a425f8728f86c3de9c606d22d
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Tue, 23 May 2023 16:20:12 +0200
io::teestream: implement writer
Signed-off-by: Armin Preiml <apreiml@strohwolke.at>
Diffstat:
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/io/tee.ha b/io/tee.ha
@@ -4,22 +4,23 @@
export type teestream = struct {
vtable: stream,
- source: handle,
+ h: handle,
sink: handle,
};
const tee_vtable: vtable = vtable {
reader = &tee_read,
+ writer = &tee_write,
...
};
-// Creates a reader which copies reads into a sink before forwarding them to the
-// caller. This stream does not need to be closed, and closing it will not close
-// the secondary streams.
-export fn tee(source: handle, sink: handle) teestream = {
+// Creates a stream which copies writes and reads into 'sink' after forwarding
+// them to the handle 'h'. This stream does not need to be closed, and closing
+// it will not close the secondary stream.
+export fn tee(h: handle, sink: handle) teestream = {
return teestream {
vtable = &tee_vtable,
- source = source,
+ h = h,
sink = sink,
...
};
@@ -27,7 +28,7 @@ export fn tee(source: handle, sink: handle) teestream = {
fn tee_read(s: *stream, buf: []u8) (size | EOF | error) = {
let s = s: *teestream;
- let z = match (read(s.source, buf)?) {
+ let z = match (read(s.h, buf)?) {
case EOF =>
return EOF;
case let z: size =>
@@ -38,3 +39,12 @@ fn tee_read(s: *stream, buf: []u8) (size | EOF | error) = {
};
return z;
};
+
+fn tee_write(s: *stream, buf: const []u8) (size | error) = {
+ let s = s: *teestream;
+ const z = write(s.h, buf)?;
+ for (let n = 0z; n < z) {
+ n += write(s.sink, buf[n..z])?;
+ };
+ return z;
+};