diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-05-28 06:52:12 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-05-28 06:52:12 -0700 |
commit | 31921a308074679a6fec36aa06a75df154f6bd21 (patch) | |
tree | 9c305e113149d69122c1045c3a98c8cb546c70fa | |
parent | 41db431321741fd89391278cddbf8b7a665eb6ba (diff) | |
download | txr-31921a308074679a6fec36aa06a75df154f6bd21.tar.gz txr-31921a308074679a6fec36aa06a75df154f6bd21.tar.bz2 txr-31921a308074679a6fec36aa06a75df154f6bd21.zip |
buf: implement fill_buf operation for buf streams.
* buf.c (buf_strm_fill_buf): New function.
(buf_strm_ops): Wire in buf_strm_fill_buf operation.
* tests/018/streams.tl: New tests.
-rw-r--r-- | buf.c | 26 | ||||
-rw-r--r-- | tests/018/streams.tl | 13 |
2 files changed, 38 insertions, 1 deletions
@@ -52,6 +52,8 @@ #include "txr.h" #include "buf.h" +#define min(a, b) ((a) < (b) ? (a) : (b)) + static struct buf *buf_handle(val buf, val ctx); static cnum buf_check_len(val len, val self) @@ -1196,6 +1198,28 @@ static val buf_strm_unget_byte(val stream, int byte) return num_fast(byte); } +static ucnum buf_strm_fill_buf(val stream, mem_t *ptr, ucnum len, ucnum pos) +{ + val self = lit("fill-buf"); + struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle); + struct buf *b = us_buf_handle(s->buf); + + if (convert(size_t, len) != len || len > INT_PTR_MAX) + uw_throwf(error_s, lit("~a: buffer too large"), self, nao); + if (pos >= len) { + return len; + } else { + size_t index = c_unum(s->pos, self); + size_t room = len - pos; + size_t avail = c_u(b->size) - index; + size_t copy = min(room, avail); + memcpy(ptr + pos, b->data + index, copy); + s->pos = plus(s->pos, unum(copy)); + return pos + copy; + } +} + + static val buf_strm_seek(val stream, val offset, enum strm_whence whence) { val self = lit("seek-stream"); @@ -1307,7 +1331,7 @@ static struct strm_ops buf_strm_ops = buf_strm_unget_char, buf_strm_unget_byte, 0, - 0, + buf_strm_fill_buf, 0, 0, buf_strm_seek, diff --git a/tests/018/streams.tl b/tests/018/streams.tl index 3bdab5bd..f82bc06e 100644 --- a/tests/018/streams.tl +++ b/tests/018/streams.tl @@ -236,3 +236,16 @@ (seek-stream s 0 :from-current) 0 (truncate-stream s 0) t (get-buf-from-stream s) #b'')) + +(with-in-buf-stream (s #b'00112233445566778899AABCCCDDEEFF') + (let ((b (make-buf 0))) + (mtest + (fill-buf-adjust b 0 s) 0 + b #b'' + (seek-stream s 0 :from-current) 0 + (buf-set-length b 5) 0 + (fill-buf-adjust b 0 s) 5 + b #b'0011223344' + (seek-stream s -3 :from-end) t + (fill-buf-adjust b 0 s) 3 + b #b'DDEEFF'))) |