summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,