diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-06-11 19:47:32 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-06-11 19:47:32 -0700 |
commit | c54df81f05e622bd3ce6daa0bc4ba5d3999f958d (patch) | |
tree | b926c2b5cab254dcb3d783bd3fcb50afa79ec6b3 /buf.c | |
parent | 2ec0f6e63f9c42750f09af4a7f03be832a2ca28a (diff) | |
download | txr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.tar.gz txr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.tar.bz2 txr-c54df81f05e622bd3ce6daa0bc4ba5d3999f958d.zip |
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.
Diffstat (limited to 'buf.c')
-rw-r--r-- | buf.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -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); |