commit 7a36e9e335d2ea7ecfe3d5b76fe97c1038a8577d
parent a20ec460699dc41e5b20b73210f91b8b9e204249
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 8 Feb 2022 11:13:00 +0100
io::limit: better define limit exceeded cases
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/io/+test/limit.ha b/io/+test/limit.ha
@@ -22,6 +22,7 @@ use errors;
case error =>
abort();
};
+ assert(read(&rlimit, buf) is io::EOF);
let wlimit = limitwriter(&source, 20);
match (read(&wlimit, buf)) {
@@ -41,4 +42,5 @@ use errors;
case error =>
abort();
};
+ assert(write(&wlimit, buf) as size == 0z);
};
diff --git a/io/limit.ha b/io/limit.ha
@@ -14,7 +14,8 @@ fn limitstream_create(source: handle, limit: size) limitstream = {
// Create an overlay stream that only allows a limited amount of bytes to be
// read from the underlying stream. This stream does not need to be closed, and
-// closing it does not close the underlying stream.
+// closing it does not close the underlying stream. Reading any data beyond the
+// given limit causes the reader to return [[io::EOF]].
export fn limitreader(source: handle, limit: size) limitstream = {
let stream = limitstream_create(source, limit);
stream.reader = &limit_read;
@@ -23,7 +24,8 @@ export fn limitreader(source: handle, limit: size) limitstream = {
// Create an overlay stream that only allows a limited amount of bytes to be
// written to the underlying stream. This stream does not need to be closed, and
-// closing it does not close the underlying stream.
+// closing it does not close the underlying stream. Writing beyond the given
+// limit causes the writer to return short writes (as few as zero bytes).
export fn limitwriter(source: handle, limit: size) limitstream = {
let stream = limitstream_create(source, limit);
stream.writer = &limit_write;
@@ -32,6 +34,9 @@ export fn limitwriter(source: handle, limit: size) limitstream = {
fn limit_read(s: *stream, buf: []u8) (size | EOF | error) = {
let stream = s: *limitstream;
+ if (stream.limit == 0) {
+ return io::EOF;
+ };
if (len(buf) > stream.limit) {
buf = buf[..stream.limit];
};
@@ -41,6 +46,9 @@ fn limit_read(s: *stream, buf: []u8) (size | EOF | error) = {
fn limit_write(s: *stream, buf: const []u8) (size | error) = {
let stream = s: *limitstream;
+ if (stream.limit == 0) {
+ return 0;
+ };
let slice = if (len(buf) > stream.limit) {
yield buf[..stream.limit];
} else {