hare

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

commit 678e4f644cfd39043150f015ac7339d0d7555800
parent 599f127d5a2470a1382afa4d968d1ccbe6a3dc1c
Author: Armin Preiml <apreiml@strohwolke.at>
Date:   Thu, 28 Sep 2023 07:58:08 +0200

bufio::scanner: implement io::reader

Diffstat:
Mbufio/scanner.ha | 27+++++++++++++++++++++++++++
Mbufio/scanner_test+test.ha | 12++++++++++++
2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/bufio/scanner.ha b/bufio/scanner.ha @@ -11,7 +11,13 @@ use types; def BUFSZ: size = 4096; +const scanner_vtable = io::vtable { + reader = &scan_read, + ... +}; + export type scanner = struct { + stream: io::stream, src: io::handle, buffer: []u8, // Number of bytes available in buffer @@ -31,6 +37,7 @@ export type scanner = struct { // reached. export fn newscanner(src: io::handle, maxread: size) scanner = { return scanner { + stream = &scanner_vtable, src = src, buffer = alloc([0...], BUFSZ), maxread = maxread, @@ -45,6 +52,7 @@ export fn newscanner(src: io::handle, maxread: size) scanner = { // they wish to free the underlying buffer through bufio. export fn newscanner_static(src: io::handle, buffer: []u8) scanner = { return scanner { + stream = &scanner_vtable, src = src, buffer = buffer, maxread = len(buffer), @@ -59,6 +67,25 @@ export fn finish(scan: *scanner) void = { free(scan.buffer); }; +fn scan_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = { + let scan = s: *scanner; + if (scan.pending == 0) { + match (scan_readahead(scan)?) { + case io::EOF => + return io::EOF; + case size => + yield; + }; + }; + + // Consume previous read, if any + scan_shift(scan); + + const n = if (len(buf) > scan.pending) scan.pending else len(buf); + buf[..n] = scan_consume(scan, n)[..]; + return n; +}; + // Fills up the scanner buffer with data from the underlying I/O handle. If no // space remains in the read buffer, it is expanded by BUFSZ (up to maxread). // Then, one read from the underlying I/O handle is performed and scan.pending diff --git a/bufio/scanner_test+test.ha b/bufio/scanner_test+test.ha @@ -111,3 +111,15 @@ use strings; }; }; }; + +@test fn scan_read() void = { + const expected: [_]u8 = [ + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + ]; + let in = memio::fixed(expected); + + let scanner = newscanner(&in, 2); + let result = io::drain(&scanner)!; + defer free(result); + assert(bytes::equal(expected, result)); +};