commit 3c90d8bc46e9a957bc28559a3de3698fdfecbcb6
parent 25d3f6ac79a2ee07214f02af4f31540089274d12
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 26 Feb 2021 15:42:11 -0500
io: add io::tee
Diffstat:
A | io/tee.ha | | | 34 | ++++++++++++++++++++++++++++++++++ |
1 file changed, 34 insertions(+), 0 deletions(-)
diff --git a/io/tee.ha b/io/tee.ha
@@ -0,0 +1,34 @@
+type tee_stream = struct {
+ stream: stream,
+ source: *stream,
+ sink: *stream,
+};
+
+// Creates a reader which copies reads into a sink before forwarding them to the
+// caller. Does not close the secondary streams when the tee stream is closed.
+export fn tee(source: *stream, sink: *stream) *stream = {
+ return alloc(tee_stream {
+ stream = stream {
+ reader = &tee_read,
+ closer = &tee_close,
+ ...
+ },
+ source = source,
+ sink = sink,
+ }): *io::stream;
+};
+
+fn tee_read(s: *stream, buf: []u8) (size | EOF | error) = {
+ let s = s: *tee_stream;
+ let z = match (read(s.source, buf)) {
+ err: error => return err,
+ EOF => return EOF,
+ z: size => z,
+ };
+ for (let n = 0z; n < z) {
+ n += write(s.sink, buf[n..z])?;
+ };
+ return z;
+};
+
+fn tee_close(s: *stream) void = free(s);