diff --git a/lib/std/io/stream/bytewriter.c3 b/lib/std/io/stream/bytewriter.c3 index c3ef7cc2f..c28afdcf4 100644 --- a/lib/std/io/stream/bytewriter.c3 +++ b/lib/std/io/stream/bytewriter.c3 @@ -79,19 +79,21 @@ fn void! ByteWriter.write_byte(ByteWriter* writer, char c) **/ fn usz! ByteWriter.read_from(ByteWriter* writer, Stream* reader) { + usz start_index = writer.index; if (reader.supports_available()) { - usz total_read = 0; while (usz available = reader.available()!) { writer.ensure_capacity(writer.index + available)!; - usz len = reader.read(writer.bytes[writer.index..])!; - total_read += len; - writer.index += len; + usz read = reader.read(writer.bytes[writer.index..])!; + writer.index += read; } - return total_read; + return writer.index - start_index; + } + if (writer.bytes.len == 0) + { + writer.ensure_capacity(16)!; } - usz total_read = 0; while (true) { // See how much we can read. @@ -100,12 +102,13 @@ fn usz! ByteWriter.read_from(ByteWriter* writer, Stream* reader) if (len_to_read < 16) { writer.ensure_capacity(writer.bytes.len * 2)!; + len_to_read = writer.bytes.len - writer.index; } // Read into the rest of the buffer usz read = reader.read(writer.bytes[writer.index..])!; writer.index += read; // Ok, we reached the end. - if (read < len_to_read) return total_read; + if (read < len_to_read) return writer.index - start_index; // Otherwise go another round } } @@ -116,4 +119,4 @@ StreamInterface bytewriter_interface = { .write_fn = fn (s, char[] bytes) => ((ByteWriter*)s.data).write(bytes), .write_byte_fn = fn (s, char c) => ((ByteWriter*)s.data).write_byte(c), .read_stream_fn = fn (s, reader) => ((ByteWriter*)s.data).read_from(reader), -}; \ No newline at end of file +}; diff --git a/test/unit/stdlib/io/bytestream.c3 b/test/unit/stdlib/io/bytestream.c3 index 8f7c5089a..dfee49eca 100644 --- a/test/unit/stdlib/io/bytestream.c3 +++ b/test/unit/stdlib/io/bytestream.c3 @@ -35,3 +35,44 @@ fn void! bytewriter_buffer() assert(o == "hello"); assert(@catchof(s.write("xxxx"))); } + +fn void! bytewriter_read_from() +{ + char[] data = "Lorem ipsum dolor sit amet biam."; + TestReader r = { .bytes = data }; + Stream s = r.as_stream(); + + ByteWriter bw; + bw.tinit(); + bw.read_from(&s)!; + + assert(bw.as_str() == data); +} + +module std::io; +// TestReader only has the read method to trigger the path +// in ByteWriter.read_from that does not rely on the available method. +struct TestReader +{ + char[] bytes; + usz index; +} + +fn Stream TestReader.as_stream(TestReader *r) +{ + return { .fns = &testReader_interface, .data = r }; +} + +fn usz! TestReader.read(TestReader *r, char[] bytes) +{ + usz left = r.bytes.len - r.index; + if (left == 0) return 0; + usz n = min(left, bytes.len); + mem::copy(bytes.ptr, &r.bytes[r.index], n); + r.index += n; + return n; +} + +StreamInterface testReader_interface = { + .read_fn = fn(s, char[] bytes) => ((TestReader*)s.data).read(bytes), +}; \ No newline at end of file