summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-05-24 09:40:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-05-24 09:40:45 -0700
commitbd7f8a4d7e1fb8938f2fc269a6a2b0e5773e3196 (patch)
treeabf6d8976d3c6b46adaa2322a25ca42a5a49f098
parent100a35345e2225902f1fb82a34eb8e4424aa1eac (diff)
downloadtxr-bd7f8a4d7e1fb8938f2fc269a6a2b0e5773e3196.tar.gz
txr-bd7f8a4d7e1fb8938f2fc269a6a2b0e5773e3196.tar.bz2
txr-bd7f8a4d7e1fb8938f2fc269a6a2b0e5773e3196.zip
streams: fill_buf for string byte input streams.
* stream.c (byte_in_fill_buf): New function. (byte_in_ops): Wire byte_in_fill_buf in place of generic_fill_buf.
-rw-r--r--stream.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/stream.c b/stream.c
index e7558c91..4fd134e0 100644
--- a/stream.c
+++ b/stream.c
@@ -2161,6 +2161,25 @@ static val byte_in_unget_byte(val stream, int byte)
return num_fast(byte);
}
+static ucnum byte_in_fill_buf(val stream, mem_t *ptr, ucnum len, ucnum pos)
+{
+ val self = lit("fill-buf");
+ struct byte_input *bi = coerce(struct byte_input *, stream->co.handle);
+
+ 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 room = len - pos;
+ size_t avail = bi->size - bi->index;
+ size_t copy = min(room, avail);
+ memcpy(ptr + pos, bi->buf + bi->index, copy);
+ bi->index += copy;
+ return pos + copy;
+ }
+}
+
static val byte_in_get_error(val stream)
{
struct byte_input *bi = coerce(struct byte_input *, stream->co.handle);
@@ -2186,7 +2205,7 @@ static struct strm_ops byte_in_ops =
byte_in_unget_char,
byte_in_unget_byte,
0,
- generic_fill_buf,
+ byte_in_fill_buf,
0, 0, 0, 0, 0, 0,
byte_in_get_error,
byte_in_get_error_str,