hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 21854035d2bdb0b391532ae8beab5c6183aeafdc
parent b76a7ab5a224fa229ac845e686738e086a973315
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Sat, 23 Apr 2022 00:45:29 +0200

bufio::buffered: use rbuffer as unread buffer

Implements: https://todo.sr.ht/~sircmpwn/hare/631
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mbufio/buffered.ha | 21+++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/bufio/buffered.ha b/bufio/buffered.ha @@ -36,7 +36,6 @@ export type bufstream = struct { ravail: size, wavail: size, flush: []u8, - unread: []u8, }; // Creates a stream which buffers reads and writes for the underlying stream. @@ -99,16 +98,17 @@ export fn setflush(s: *bufstream, b: []u8) void = { // Unreads a slice of bytes. The next read calls on this buffer will consume the // un-read data before consuming further data from the underlying source, or any -// buffered data. +// buffered data. The amount of data that can be un-read is guaranteed to be at +// least as much as the size of the previous read from the stream. export fn unread(s: *bufstream, buf: []u8) void = { - append(s.unread, buf...); + assert(len(buf) + s.ravail > len(s.rbuffer)); + s.rbuffer[len(buf)..len(buf) + s.ravail] = s.rbuffer[..s.ravail]; + s.rbuffer[..len(buf)] = buf; }; // Unreads a rune; see [[unread]]. -export fn unreadrune(s: *bufstream, rn: rune) void = { - const buf = utf8::encoderune(rn); - insert(s.unread[0], buf...); -}; +export fn unreadrune(s: *bufstream, rn: rune) void = + unread(s, utf8::encoderune(rn)); // Returns true if an [[io::handle]] is a [[buffered]] stream. export fn isbuffered(in: io::handle) bool = { @@ -130,13 +130,6 @@ fn buffered_close_static(s: *io::stream) void = { fn buffered_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = { assert(s.reader == &buffered_read); let s = s: *bufstream; - if (len(s.unread) != 0) { - let n = if (len(buf) < len(s.unread)) len(buf) else len(s.unread); - buf[..n] = s.unread[..n]; - delete(s.unread[..n]); - return n; - }; - let n = if (len(buf) < len(s.rbuffer)) len(buf) else len(s.rbuffer); if (n > s.ravail) { let z = match (io::read(s.source, s.rbuffer[s.ravail..])) {