diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-05-24 07:54:31 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-05-24 07:54:31 -0700 |
commit | 100a35345e2225902f1fb82a34eb8e4424aa1eac (patch) | |
tree | 755b57768b7a1d6d25f70e68d53762c5bff937ac | |
parent | f9996e535f24be8c8ac27fff58ea0feed69eaa9d (diff) | |
download | txr-100a35345e2225902f1fb82a34eb8e4424aa1eac.tar.gz txr-100a35345e2225902f1fb82a34eb8e4424aa1eac.tar.bz2 txr-100a35345e2225902f1fb82a34eb8e4424aa1eac.zip |
parser: implement fill_buf for shadow stream.
* parser.c (shadow_fill_buf): New function.
(shadow_ops_template): Wire shadow_fill_buf in place
of generic_fill_buf.
-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); |