Add io stream primitives (#1626)

* io: implement MultiReader struct

Implement a MultiReader (InStream) which sequentially read from the
provided readers (InStreams). Return IoError.EOF when all of the readers
are read.

* io: implement MultiWriter struct

Implement a MultiWriter (OutStream). The MultiWriter duplicates its
writes to all the provided writers (OutStream).

* io: implement TeeReader struct

Implement a TeeReader (InStream) which reads from a wrapped reader
(InStream) and writes data to the provided writer (OutStream).
This commit is contained in:
konimarti
2024-11-15 23:18:29 +01:00
committed by GitHub
parent a233771433
commit f3304acc93
7 changed files with 227 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
module std::io @test;
fn void! test_multireader()
{
MultiReader mr;
mr.temp_init(
&&wrap_bytes("foo"),
&&wrap_bytes(" "),
&&wrap_bytes("bar"),
&&wrap_bytes("!"),
);
defer mr.free();
ByteWriter w;
io::copy_to(&mr, w.temp_init())!;
String want = "foo bar!";
assert(w.str_view() == want,
"invalid data read; got: %s, want: %s", w.str_view(), want);
}

View File

@@ -0,0 +1,17 @@
module std::io @test;
fn void! test_multiwriter()
{
ByteWriter w1, w2;
MultiWriter mw;
mw.temp_init(w1.temp_init(), w2.temp_init());
defer mw.free();
String want = "foobar";
io::copy_to(ByteReader{}.init(want), &mw)!;
assert(w1.str_view() == want,
"invalid write; got: %s, want: %s", w1.str_view(), want);
assert(w2.str_view() == want,
"invalid write; got: %s, want: %s", w2.str_view(), want);
}

View File

@@ -0,0 +1,17 @@
module std::io @test;
fn void! test_teereader()
{
String want = "foobar";
ByteWriter w;
TeeReader r = tee_reader(ByteReader{}.init(want), w.temp_init());
char[16] buf;
usz n = r.read(buf[..])!;
String got = w.str_view();
assert(n == want.len, "teereader: invalid length");
assert(got == want, "teereader: got: %s, want: %s", got, want);
assert(got == (String)buf[:n], "teereader: got: %s, want: %s", got, (String)buf[:n]);
}