From c54df81f05e622bd3ce6daa0bc4ba5d3999f958d Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 11 Jun 2019 19:47:32 -0700 Subject: buffers: allow sub operation. * buf.c (sub_buf): New function. * buf.h (sub_buf): Declared. * lib.c (sub): Hook in BUF type. (replace): Diagnose BUF specially as unsupported. --- buf.c | 32 ++++++++++++++++++++++++++++++++ buf.h | 1 + lib.c | 8 +++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/buf.c b/buf.c index 5e5a5d66..06fb0abf 100644 --- a/buf.c +++ b/buf.c @@ -239,6 +239,38 @@ void buf_fill(val buf, mem_t *src, val self) memcpy(b->data, src, c_num(b->len)); } +val sub_buf(val buf, val from, val to) +{ + struct buf *b = buf_handle(buf, lit("sub")); + val len = b->len; + + if (null_or_missing_p(from)) + from = zero; + else if (from == t) + from = len; + else if (lt(from, zero)) { + from = plus(from, len); + if (to == zero) + to = len; + } + + if (null_or_missing_p(to) || to == t) + to = len; + else if (lt(to, zero)) + to = plus(to, len); + + from = max2(zero, min2(from, len)); + to = max2(zero, min2(to, len)); + + if (ge(from, to)) { + return make_buf(zero, nil, zero); + } else if (from == 0 && to == len) { + return buf; + } else { + return make_duplicate_buf(minus(to, from), b->data + c_num(from)); + } +} + static void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) { struct buf *b = buf_handle(buf, self); diff --git a/buf.h b/buf.h index 60004112..db83f2a3 100644 --- a/buf.h +++ b/buf.h @@ -37,6 +37,7 @@ val length_buf(val buf); val buf_alloc_size(val buf); mem_t *buf_get(val buf, val self); void buf_fill(val buf, mem_t *src, val self); +val sub_buf(val seq, val from, val to); #if HAVE_I8 val buf_put_i8(val buf, val pos, val num); diff --git a/lib.c b/lib.c index e3e1909e..1794fa99 100644 --- a/lib.c +++ b/lib.c @@ -9996,6 +9996,8 @@ val sub(val seq, val from, val to) return sub_str(seq, from, to); case VEC: return sub_vec(seq, from, to); + case BUF: + return sub_buf(seq, from, to); case COBJ: if (seq->co.cls == carray_s) return carray_sub(seq, from, to); @@ -10097,6 +10099,8 @@ val refset(val seq, val ind, val newval) val replace(val seq, val items, val from, val to) { + val self = lit("replace"); + switch (type(seq)) { case NIL: case CONS: @@ -10114,8 +10118,10 @@ val replace(val seq, val items, val from, val to) if (obj_struct_p(seq)) return replace_obj(seq, items, from, to); /* fallthrough */ + case BUF: + type_mismatch(lit("~a: operation doesn't support buf type"), self, nao); default: - type_mismatch(lit("replace: ~s is not a sequence"), seq, nao); + type_mismatch(lit("~a: ~s is not a sequence"), self, seq, nao); } } -- cgit v1.2.3