The buffer contents are now only moved to index 0 whenever new data is
to be read from the underlying reader. The start of buffered data is
tracked by the new rpos field.
Some room for improvement remains (ring buffer, maybe?), but at least it
performs better than no buffering...
Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>
---
bufio/buffered.ha | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/bufio/buffered.ha b/bufio/buffered.ha
index e7c5f2e7..6e17eabb 100644
--- a/bufio/buffered.ha
@@ -33,6 +33,7 @@ export type bufstream = struct {
source: io::handle,
rbuffer: []u8,
wbuffer: []u8,
+ rpos: size,
ravail: size,
wavail: size,
flush: []u8,
@@ -79,6 +80,7 @@ export fn buffered(
rbuffer = rbuf,
wbuffer = wbuf,
flush = flush_default,
+ rpos = len(rbuf), // necessary for unread() before read()
...
};
};
@@ -135,10 +137,10 @@ export fn unread(s: io::handle, buf: []u8) void = {
case =>
abort("Attempted unread on unbuffered stream");
};
- assert(len(s.rbuffer) - s.ravail >= len(buf),
+ assert(s.rpos >= len(buf),
"Attempted to unread more data than buffer has available");
- let sl = s.rbuffer[..s.ravail];
- static insert(sl[0], buf...);
+ s.rbuffer[s.rpos - len(buf)..s.rpos] = buf;
+ s.rpos -= len(buf);
s.ravail += len(buf);
};
@@ -168,26 +170,25 @@ fn buffered_close_static(s: *io::stream) (void | io::error) = {
fn buffered_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
assert(s.reader == &buffered_read);
let s = s: *bufstream;
- 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..])) {
+
+ if (s.ravail < len(buf) && s.ravail < len(s.rbuffer)) {
+ s.rbuffer[..s.ravail] = s.rbuffer[s.rpos..s.rpos + s.ravail];
+ s.rpos = 0;
+ match (io::read(s.source, s.rbuffer[s.ravail..])) {
case let err: io::error =>
return err;
case io::EOF =>
if (s.ravail == 0) {
return io::EOF;
};
- yield 0z;
case let z: size =>
- yield z;
+ s.ravail += z;
};
- s.ravail += z;
- n = if (n > s.ravail) s.ravail else n;
- assert(n != 0);
};
- buf[..n] = s.rbuffer[..n];
- s.rbuffer[..len(s.rbuffer) - n] = s.rbuffer[n..];
+ const n = if (len(buf) < s.ravail) len(buf) else s.ravail;
+ buf[..n] = s.rbuffer[s.rpos..s.rpos + n];
+ s.rpos += n;
s.ravail -= n;
return n;
};
--
2.39.2
Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>
---
bufio/buffered.ha | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/bufio/buffered.ha b/bufio/buffered.ha
index 6e17eabb..982f481a 100644
--- a/bufio/buffered.ha
@@ -199,11 +199,13 @@ fn buffered_write(s: *io::stream, buf: const []u8) (size | io::error) = {
let buf = buf;
let doflush = false;
- for (let i = 0z; i < len(buf); i += 1) {
- for (let j = 0z; j < len(s.flush); j += 1) {
- if (buf[i] == s.flush[j]) {
- doflush = true;
- break;
+ if (len(s.flush) != 0) {
+ for (let i = 0z; i < len(buf); i += 1) :search {
+ for (let j = 0z; j < len(s.flush); j += 1) {
+ if (buf[i] == s.flush[j]) {
+ doflush = true;
+ break :search;
+ };
};
};
};
--
2.39.2