diff options
-rw-r--r-- | parser.c | 26 |
1 files changed, 25 insertions, 1 deletions
@@ -77,6 +77,8 @@ #define SHADOW_TAB_SIZE 16 +#define min(a, b) ((a) < (b) ? (a) : (b)) + val parser_s, unique_s, circref_s; val listener_hist_len_s, listener_multi_line_p_s, listener_sel_inclusive_p_s; val listener_pprint_s, listener_greedy_eval_s, listener_auto_compound_s; @@ -2240,6 +2242,28 @@ static ucnum shadow_put_buf(val stream, mem_t *ptr, ucnum len, ucnum pos) return ops->put_buf(stream, ptr, len, pos); } +static ucnum shadow_fill_buf(val stream, mem_t *ptr, ucnum len, ucnum pos) +{ + val self = lit("fill-buf"); + struct strm_base *s = coerce(struct strm_base *, stream->co.handle); + struct shadow_context *sc = coerce(struct shadow_context *, s->shadow_obj); + + 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 = sc->size - sc->index; + size_t copy = min(room, avail); + memcpy(ptr + pos, sc->buf + sc->index, copy); + sc->index += copy; + if (copy == avail) + shadow_detach(stream); + return pos + copy; + } +} + static val shadow_close(val stream, val throw_on_error) { struct strm_ops *ops = shadow_detach(stream); @@ -2275,7 +2299,7 @@ static struct strm_ops shadow_ops_template = shadow_put_string, shadow_put_char, shadow_put_byte, generic_get_line, shadow_get_char, shadow_get_byte, shadow_unget_char, shadow_unget_byte, - shadow_put_buf, generic_fill_buf, + shadow_put_buf, shadow_fill_buf, shadow_close, shadow_flush, shadow_seek, shadow_truncate, 0, 0, 0, 0, 0, 0); |