commit c929eb16a3d1a99d54acfc055778b30367fc2bec
parent 81f1b58d3ec9c41568677179b86052a077506ebe
Author: Sebastian <sebastian@sebsite.pw>
Date: Tue, 17 Oct 2023 21:09:47 -0400
bufio: allow unreading more than scan.readout
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/bufio/scanner.ha b/bufio/scanner.ha
@@ -271,9 +271,18 @@ fn scan_unread(scan: *scanner, buf: []u8) void = {
if (len(buf) == 0) {
return;
};
- assert(len(buf) <= scan.readout);
- scan.buffer[scan.readout - len(buf)..scan.readout] = buf;
- scan.readout -= len(buf);
+ if (len(buf) <= scan.readout) {
+ scan.buffer[scan.readout - len(buf)..scan.readout] = buf;
+ scan.readout -= len(buf);
+ } else {
+ const n = len(buf) - scan.readout;
+ assert(n < scan.maxread - scan.pending,
+ "Attempted to unread more data than buffer has available");
+ scan.buffer[n..] = scan.buffer[..len(scan.buffer) - n];
+ scan.pending += n;
+ scan.buffer[..len(buf)] = buf;
+ scan.readout = 0;
+ };
};
// Reads a single byte from an [[io::handle]].
diff --git a/bufio/scanner_test+test.ha b/bufio/scanner_test+test.ha
@@ -158,8 +158,12 @@ use strings;
let l = scan_line(&scanner)! as const str;
assert(l == "See?");
+ let b = scan_rune(&scanner) as rune;
+ unreadrune(&scanner, b);
+ unreadrune(&scanner, ' ');
+ unread(&scanner, strings::toutf8("I'm"));
let l = scan_line(&scanner)! as const str;
- assert(l == "Done!");
+ assert(l == "I'm Done!");
assert(scan_line(&scanner) is io::EOF);
};