summaryrefslogtreecommitdiffstats
path: root/buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'buf.c')
-rw-r--r--buf.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/buf.c b/buf.c
index 360d5bec..d5782dc2 100644
--- a/buf.c
+++ b/buf.c
@@ -1086,7 +1086,6 @@ struct buf_strm {
int is_byte_oriented;
val buf;
val pos;
- val unget_c;
};
static void buf_strm_mark(val stream)
@@ -1095,7 +1094,6 @@ static void buf_strm_mark(val stream)
strm_base_mark(&b->a);
gc_mark(b->buf);
gc_mark(b->pos);
- gc_mark(b->unget_c);
}
static int buf_strm_put_byte_callback(int b, mem_t *ctx)
@@ -1147,23 +1145,18 @@ static int buf_strm_get_byte_callback(mem_t *ctx)
static val buf_strm_get_char(val stream)
{
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
+ wint_t ch;
- if (s->unget_c) {
- return rcyc_pop(&s->unget_c);
+ if (s->is_byte_oriented) {
+ ch = buf_strm_get_byte_callback(coerce(mem_t *, s));
+ if (ch == 0)
+ ch = 0xDC00;
} else {
- wint_t ch;
-
- if (s->is_byte_oriented) {
- ch = buf_strm_get_byte_callback(coerce(mem_t *, s));
- if (ch == 0)
- ch = 0xDC00;
- } else {
- ch = utf8_decode(&s->ud, buf_strm_get_byte_callback,
- coerce(mem_t *, s));
- }
-
- return (ch != WEOF) ? chr(ch) : nil;
+ ch = utf8_decode(&s->ud, buf_strm_get_byte_callback,
+ coerce(mem_t *, s));
}
+
+ return (ch != WEOF) ? chr(ch) : nil;
}
static val buf_strm_get_byte(val stream)
@@ -1175,8 +1168,28 @@ static val buf_strm_get_byte(val stream)
static val buf_strm_unget_char(val stream, val ch)
{
+ val self = lit("unget-char");
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
- mpush(ch, mkloc(s->unget_c, stream));
+ struct buf *b = us_buf_handle(s->buf);
+ struct utf8_tiny_buf bu;
+ unsigned char *bend = bu.buf + sizeof bu.buf;
+ ucnum index = c_unum(s->pos, self);
+
+ bu.ptr = bend;
+
+ (void) utf8_encode(c_chr(ch), utf8_tiny_buf_putc, coerce(mem_t *, &bu));
+
+ if (convert(size_t, bend - bu.ptr) > index) {
+ uw_throwf(file_error_s,
+ lit("~a: cannot push back past start of stream ~s"),
+ stream, self, nao);
+ }
+
+ while (bu.ptr < bend)
+ b->data[--index] = *bu.ptr++;
+
+ s->pos = unum(index);
+
return ch;
}
@@ -1367,7 +1380,6 @@ val make_buf_stream(val buf_opt)
s->buf = nil;
s->pos = zero;
s->is_byte_oriented = 0;
- s->unget_c = nil;
stream = cobj(coerce(mem_t *, s), stream_cls, &buf_strm_ops.cobj_ops);
s->buf = buf;