summaryrefslogtreecommitdiffstats
path: root/buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'buf.c')
-rw-r--r--buf.c422
1 files changed, 225 insertions, 197 deletions
diff --git a/buf.c b/buf.c
index 41de5b28..73695e7d 100644
--- a/buf.c
+++ b/buf.c
@@ -52,40 +52,64 @@
#include "txr.h"
#include "buf.h"
+#define BUF_BORROWED UINT_PTR_MAX
+
#define min(a, b) ((a) < (b) ? (a) : (b))
static struct buf *buf_handle(val buf, val ctx);
-static cnum buf_check_len(val len, val self)
+static ucnum buf_check_len(val len, val self)
{
- cnum l = c_num(len, self);
- if (l < 0)
+ if (minusp(len)) {
uw_throwf(error_s, lit("~a: negative length ~s specified"),
self, len, nao);
- return l;
+ } else {
+ ucnum l = c_unum(len, self);
+
+ if (l == BUF_BORROWED)
+ uw_throwf(error_s, lit("~a: reserved length value ~s specified"),
+ self, len, nao);
+
+ return l;
+ }
}
-static cnum buf_check_alloc_size(val alloc_size, cnum len, val self)
+static ucnum buf_check_alloc_size(val alloc_size, ucnum len, val self)
{
- cnum ah = c_num(alloc_size, self);
- if (ah < len)
+ ucnum as = c_unum(alloc_size, self);
+
+ if (as == BUF_BORROWED)
+ uw_throwf(error_s, lit("~a: reserved alloc size value ~s specified"),
+ self, alloc_size, nao);
+
+ if (as < len)
uw_throwf(error_s, lit("~a: alloc size size ~s lower than length"),
self, alloc_size, nao);
- return ah;
+
+ return as;
}
-static cnum buf_check_index(struct buf *b, val index, val self)
+static ucnum buf_check_index(struct buf *b, val index_in, val self)
{
- cnum ix = c_num(index, self);
- if (ix < 0)
- ix = c_num(plus(b->len, index), self);
- if (ix < 0)
+ val index = minusp(index_in) ? plus(unum(b->len), index_in) : index_in;
+ ucnum ix;
+
+ if (minusp(index)) {
uw_throwf(error_s, lit("~a: negative byte index ~s specified"),
self, index, nao);
+ }
+
+ ix = c_unum(index, self);
+
+ if (ix >= BUF_BORROWED - 1) {
+ uw_throwf(error_s, lit("~a: index ~s disallowed"),
+ self, index, nao);
+ }
+
return ix;
}
-static void err_oflow(val self)
+NORETURN static void err_oflow(val self)
{
uw_throwf(error_s, lit("~a: array size overflow"), self, nao);
}
@@ -137,7 +161,7 @@ static void prepare_pattern(mem_t **ppat, mem_t **pfree, mem_t pbuf[SIZEOF_PTR],
case BUF:
{
struct buf *pb = buf_handle(pat, self);
- ucnum l = c_unum(pb->len, self);
+ ucnum l = pb->len;
if (l > 0) {
*ppat = pb->data;
@@ -157,9 +181,9 @@ val make_buf(val len, val init_pat, val alloc_size)
{
val self = lit("make-buf");
val pat = default_arg(init_pat, zero);
- cnum blen = buf_check_len(len, self);
+ ucnum blen = buf_check_len(len, self);
val alloc = if3(null_or_missing_p(alloc_size), len, alloc_size);
- cnum size = buf_check_alloc_size(alloc, blen, self);
+ ucnum size = buf_check_alloc_size(alloc, blen, self);
mem_t *data = if3(pat == zero && size == blen,
chk_calloc(size, 1),
chk_malloc(size));
@@ -168,8 +192,8 @@ val make_buf(val len, val init_pat, val alloc_size)
obj->b.type = BUF;
obj->b.data = data;
- obj->b.len = len;
- obj->b.size = num(size);
+ obj->b.len = blen;
+ obj->b.size = size;
if ((is_num(pat) || is_chr(pat)) &&
-256 < (iv = c_num(pat, self)) && iv < 256)
@@ -210,45 +234,51 @@ val bufp(val object)
return tnil(type(object) == BUF);
}
-val init_borrowed_buf(obj_t *obj, val len, mem_t *data)
+val init_borrowed_buf(obj_t *obj, ucnum len, mem_t *data)
{
obj->b.type = BUF;
obj->b.data = data;
obj->b.len = len;
- obj->b.size = nil;
+ obj->b.size = BUF_BORROWED;
return obj;
}
-val make_borrowed_buf(val len, mem_t *data)
+val make_borrowed_buf(ucnum len, mem_t *data)
{
return init_borrowed_buf(make_obj(), len, data);
}
-val make_duplicate_buf(val len, mem_t *data)
+val make_duplicate_buf(ucnum len, mem_t *data, val self)
{
- val self = lit("make-duplicate-buf");
- val obj = make_obj();
+ if (len < BUF_BORROWED) {
+ val obj = make_obj();
- obj->b.type = BUF;
- obj->b.data = chk_copy_obj(data, c_num(len, self));
- obj->b.len = len;
- obj->b.size = len;
+ obj->b.type = BUF;
+ obj->b.data = chk_copy_obj(data, len);
+ obj->b.len = len;
+ obj->b.size = len;
- return obj;
+ return obj;
+ } else {
+ err_oflow(self);
+ }
}
-val make_owned_buf(val len, mem_t *data)
+val make_owned_buf(ucnum len, mem_t *data, val self)
{
- val buf = make_borrowed_buf(len, data);
- buf->b.size = len;
- return buf;
+ if (len < BUF_BORROWED) {
+ val buf = make_borrowed_buf(len, data);
+ buf->b.size = len;
+ return buf;
+ } else {
+ err_oflow(self);
+ }
}
-static val make_ubuf(ucnum clen)
+static val make_ubuf(ucnum len)
{
- mem_t *data = chk_malloc(clen);
- val len = unum(clen);
+ mem_t *data = chk_malloc(len);
val buf = make_borrowed_buf(len, data);
buf->b.size = len;
return buf;
@@ -269,22 +299,22 @@ INLINE struct buf *us_buf_handle(val buf)
val copy_buf(val buf)
{
- struct buf *b = buf_handle(buf, lit("copy-buf"));
- return if3(b->size,
- make_duplicate_buf(b->len, b->data),
+ val self = lit("copy-buf");
+ struct buf *b = buf_handle(buf, self);
+ return if3(b->size != BUF_BORROWED,
+ make_duplicate_buf(b->len, b->data, self),
make_borrowed_buf(b->len, b->data));
}
static void buf_shrink(struct buf *b)
{
- val self = lit("buf-trim");
- val len = b->len;
+ ucnum len = b->len;
- if (len == zero)
- len = succ(len); /* avoid reallocing to zero length; i.e. freeing */
+ if (len == 0)
+ len = 1; /* avoid zero size realloc */
if (len != b->size) {
- b->data = chk_realloc(b->data, c_unum(len, self));
+ b->data = chk_realloc(b->data, len);
b->size = b->len;
}
}
@@ -293,27 +323,25 @@ val buf_trim(val buf)
{
val self = lit("buf-trim");
struct buf *b = buf_handle(buf, self);
- val oldsize = b->size;
- if (!oldsize)
+ ucnum oldsize = b->size;
+ if (oldsize == BUF_BORROWED)
uw_throwf(error_s, lit("~a: ~s is a fixed buffer"),
self, buf, nao);
buf_shrink(b);
- return oldsize;
+ return unum(oldsize);
}
-static val buf_do_set_len(val buf, struct buf *b, val newlen,
+static val buf_do_set_len(val buf, struct buf *b, ucnum len,
val init_pat, val self)
{
- val oldlen = b->len;
- cnum olen = c_num(oldlen, self), len = c_num(newlen, self);
- cnum oldsize = c_num(b->size, self), size = oldsize;
+ ucnum olen = b->len;
+ ucnum oldsize = b->size, size = oldsize;
- if (!b->size)
+ if (b->size == BUF_BORROWED)
uw_throwf(error_s, lit("~a: ~s is a fixed buffer"),
self, buf, nao);
- (void) buf_check_len(newlen, self);
- b->len = newlen;
+ b->len = len;
if (size < len) {
if (size > INT_PTR_MAX - INT_PTR_MAX / 5) {
@@ -327,7 +355,7 @@ static val buf_do_set_len(val buf, struct buf *b, val newlen,
if (size > oldsize) {
b->data = chk_realloc(b->data, size);
- b->size = num(size);
+ b->size = size;
}
if (len > olen) {
@@ -364,24 +392,24 @@ static val buf_do_set_len(val buf, struct buf *b, val newlen,
}
}
- return oldlen;
+ return unum(olen);
}
val buf_set_length(val buf, val len, val init_val)
{
val self = lit("buf-set-len");
struct buf *b = buf_handle(buf, self);
- return buf_do_set_len(buf, b, len, init_val, self);
+ ucnum l = buf_check_len(len, self);
+ return buf_do_set_len(buf, b, l, init_val, self);
}
val buf_free(val buf)
{
val self = lit("buf-free");
struct buf *b = buf_handle(buf, self);
- if (b->size) {
+ if (b->size != BUF_BORROWED) {
free(b->data);
b->data = 0;
- b->len = b->size = zero;
return t;
}
return nil;
@@ -391,14 +419,14 @@ val length_buf(val buf)
{
val self = lit("length-buf");
struct buf *b = buf_handle(buf, self);
- return b->len;
+ return unum(b->len);
}
val buf_alloc_size(val buf)
{
val self = lit("buf-alloc-size");
struct buf *b = buf_handle(buf, self);
- return b->size;
+ return b->size == BUF_BORROWED ? nil : unum(b->size);
}
mem_t *buf_get(val buf, val self)
@@ -410,8 +438,8 @@ mem_t *buf_get(val buf, val self)
val sub_buf(val buf, val from, val to)
{
val self = lit("sub-buf");
- struct buf *b = buf_handle(buf, lit("sub"));
- val len = b->len;
+ struct buf *b = buf_handle(buf, self);
+ val len = unum(b->len);
if (null_or_missing_p(from))
from = zero;
@@ -436,7 +464,8 @@ val sub_buf(val buf, val from, val to)
} else if (from == zero && to == len) {
return buf;
} else {
- return make_duplicate_buf(minus(to, from), b->data + c_num(from, self));
+ return make_duplicate_buf(buf_check_len(minus(to, from), self),
+ b->data + c_num(from, self), self);
}
}
@@ -451,8 +480,8 @@ val replace_buf(val buf, val items, val from, val to)
from = len;
} else if (!integerp(from)) {
seq_iter_t wh_iter, item_iter;
- cnum offs = 0;
- cnum l = c_num(len, self), ol = l;
+ ucnum offs = 0;
+ ucnum l = c_unum(len, self), ol = l;
val wh, item;
seq_iter_init(self, &wh_iter, from);
seq_iter_init(self, &item_iter, items);
@@ -480,7 +509,7 @@ val replace_buf(val buf, val items, val from, val to)
w -= offs;
- if (w >= l)
+ if (l <= INT_PTR_MAX && w >= convert(cnum, l))
break;
memmove(buf->b.data + w,
@@ -516,8 +545,8 @@ val replace_buf(val buf, val items, val from, val to)
if (gt(len_rep, len_it)) {
val len_diff = minus(len_rep, len_it);
- cnum t = c_num(to, self);
- cnum l = c_num(len, self);
+ ucnum t = c_unum(to, self);
+ ucnum l = c_unum(len, self);
memmove(buf->b.data + t - c_num(len_diff, self),
buf->b.data + t,
@@ -527,8 +556,8 @@ val replace_buf(val buf, val items, val from, val to)
to = plus(from, len_it);
} else if (lt(len_rep, len_it)) {
val len_diff = minus(len_it, len_rep);
- cnum t = c_num(to, self);
- cnum l = c_num(len, self);
+ ucnum t = c_unum(to, self);
+ ucnum l = c_unum(len, self);
buf_set_length(buf, plus(len, len_diff), zero);
@@ -544,8 +573,8 @@ val replace_buf(val buf, val items, val from, val to)
memmove(buf->b.data + c_num(from, self), items->b.data, c_num(len_it, self));
} else {
seq_iter_t item_iter;
- cnum f = c_num(from, self);
- cnum t = c_num(to, self);
+ ucnum f = c_unum(from, self);
+ ucnum t = c_unum(to, self);
seq_iter_init(self, &item_iter, items);
@@ -562,26 +591,29 @@ val replace_buf(val buf, val items, val from, val to)
val buf_list(val list)
{
val self = lit("buf-list");
- val len = length(list);
- val buf = make_buf(zero, zero, len);
+ val buf = make_buf(zero, zero, num_fast(32));
+ struct buf *b = us_buf_handle(buf);
seq_iter_t iter;
val elem;
- cnum i;
-
- for (i = 0, seq_iter_init(self, &iter, list); seq_get(&iter, &elem); i++)
- buf->b.data[i] = c_uchar(elem, self);
+ ucnum i;
- buf->b.len = len;
+ for (i = 0, seq_iter_init(self, &iter, list); seq_get(&iter, &elem); i++) {
+ if (i + 1 < i)
+ err_oflow(self);
+ buf_do_set_len(buf, b, i + 1, elem, self);
+ }
return buf;
}
-static void buf_move_bytes(val buf, val pos, mem_t *ptr, cnum size, val self)
+static void buf_move_bytes(val buf, val pos, mem_t *ptr, ucnum size, val self)
{
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
- val req_len = plus(num(p), num(size));
- if (gt(req_len, b->len))
+ ucnum p = buf_check_index(b, pos, self);
+ ucnum req_len = p + size;
+ if (req_len < p)
+ err_oflow(self);
+ if (req_len > b->len)
buf_do_set_len(buf, b, req_len, nil, self);
memmove(b->data + p, ptr, size);
}
@@ -590,7 +622,7 @@ val buf_put_buf(val dbuf, val pos, val sbuf)
{
val self = lit("buf-put-buf");
struct buf *sb = buf_handle(sbuf, self);
- buf_move_bytes(dbuf, pos, sb->data, c_num(sb->len, self), self);
+ buf_move_bytes(dbuf, pos, sb->data, sb->len, self);
return sbuf;
}
@@ -602,14 +634,9 @@ static val compat_buf_put_buf(val dbuf, val pos, val sbuf)
return buf_put_buf(dbuf, pos, sbuf);
}
-void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self)
+void buf_put_bytes(val buf, val pos, mem_t *ptr, ucnum size, val self)
{
- struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
- val req_len = plus(num(p), num(size));
- if (gt(req_len, b->len))
- buf_do_set_len(buf, b, req_len, nil, self);
- memcpy(b->data + p, ptr, size);
+ return buf_move_bytes(buf, pos, ptr, size, self);
}
#if HAVE_I8
@@ -617,10 +644,10 @@ val buf_put_i8(val buf, val pos, val num)
{
val self = lit("buf-put-i8");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
+ ucnum p = buf_check_index(b, pos, self);
i8_t v = c_i8(num, self);
- if (p >= c_num(b->len, self))
- buf_do_set_len(buf, b, succ(pos), nil, self);
+ if (p >= b->len)
+ buf_do_set_len(buf, b, p + 1, nil, self);
b->data[p] = v;
return num;
}
@@ -629,10 +656,10 @@ val buf_put_u8(val buf, val pos, val num)
{
val self = lit("buf-put-u8");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
+ ucnum p = buf_check_index(b, pos, self);
cnum v = c_u8(num, self);
- if (p >= c_num(b->len, self))
- buf_do_set_len(buf, b, succ(pos), nil, self);
+ if (p >= b->len)
+ buf_do_set_len(buf, b, p + 1, nil, self);
b->data[p] = v;
return num;
}
@@ -696,10 +723,10 @@ val buf_put_char(val buf, val pos, val num)
{
val self = lit("buf-put-char");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
+ ucnum p = buf_check_index(b, pos, self);
char v = c_char(num, self);
- if (p >= c_num(b->len, self))
- buf_do_set_len(buf, b, succ(pos), nil, self);
+ if (p >= b->len)
+ buf_do_set_len(buf, b, p + 1, nil, self);
b->data[p] = v;
return num;
}
@@ -708,10 +735,10 @@ val buf_put_uchar(val buf, val pos, val num)
{
val self = lit("buf-put-uchar");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
+ ucnum p = buf_check_index(b, pos, self);
unsigned char v = c_uchar(num, self);
- if (p >= c_num(b->len, self))
- buf_do_set_len(buf, b, succ(pos), nil, self);
+ if (p >= b->len)
+ buf_do_set_len(buf, b, p + 1, nil, self);
b->data[p] = v;
return num;
}
@@ -794,14 +821,17 @@ val buf_put_cptr(val buf, val pos, val cptr)
return cptr;
}
-void buf_get_bytes(val buf, val pos, mem_t *ptr, cnum size, val self)
+void buf_get_bytes(val buf, val pos, mem_t *ptr, ucnum size, val self)
{
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
- cnum e = p + size;
- cnum l = c_num(b->len, self);
+ ucnum p = buf_check_index(b, pos, self);
+ ucnum e = p + size;
+ ucnum l = b->len;
- if (e > l || e < 0)
+ if (e < p)
+ err_oflow(self);
+
+ if (e > l)
uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao);
memcpy(ptr, b->data + p, size);
@@ -812,8 +842,8 @@ val buf_get_i8(val buf, val pos)
{
val self = lit("buf-get-i8");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
- if (p >= c_num(b->len, self))
+ ucnum p = buf_check_index(b, pos, self);
+ if (p >= b->len)
uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao);
return num_fast(convert(i8_t, b->data[p]));
}
@@ -822,8 +852,8 @@ val buf_get_u8(val buf, val pos)
{
val self = lit("buf-get-u8");
struct buf *b = buf_handle(buf, self);
- cnum p = buf_check_index(b, pos, self);
- if (p >= c_num(b->len, self))
+ ucnum p = buf_check_index(b, pos, self);
+ if (p >= b->len)
uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao);
return num_fast(convert(u8_t, b->data[p]));
}
@@ -996,7 +1026,7 @@ val buf_print(val buf, val stream_in)
val self = lit("buf-print");
val stream = default_arg(stream_in, std_output);
struct buf *b = buf_handle(buf, self);
- cnum len = c_num(b->len, self), count = 0;
+ ucnum len = b->len, count = 0;
mem_t *data = b->data;
val save_mode = test_neq_set_indent_mode(stream, num_fast(indent_foff),
num_fast(indent_data));
@@ -1028,7 +1058,7 @@ val buf_pprint(val buf, val stream_in)
val self = lit("buf-pprint");
val stream = default_arg(stream_in, std_output);
struct buf *b = buf_handle(buf, self);
- cnum len = c_num(b->len, self);
+ ucnum len = b->len;
mem_t *data = b->data;
if (opt_compat && opt_compat <= 294) {
@@ -1045,7 +1075,7 @@ val buf_pprint(val buf, val stream_in)
val buf_str_sep(val buf, val sep, val self)
{
struct buf *b = buf_handle(buf, self);
- ucnum len = c_unum(b->len, self);
+ ucnum len = b->len;
val ret = null_string;
if (len > 0) {
@@ -1085,7 +1115,7 @@ struct buf_strm {
utf8_decoder_t ud;
int is_byte_oriented;
val buf;
- val pos;
+ ucnum pos;
};
static void buf_strm_mark(val stream)
@@ -1093,14 +1123,13 @@ static void buf_strm_mark(val stream)
struct buf_strm *b = coerce(struct buf_strm *, stream->co.handle);
strm_base_mark(&b->a);
gc_mark(b->buf);
- gc_mark(b->pos);
}
static int buf_strm_put_byte_callback(int b, mem_t *ctx)
{
struct buf_strm *s = coerce(struct buf_strm *, ctx);
- (void) buf_put_uchar(s->buf, s->pos, num_fast(b));
- s->pos = succ(s->pos);
+ (void) buf_put_uchar(s->buf, unum(s->pos), num_fast(b));
+ s->pos++;
return 1;
}
@@ -1134,12 +1163,9 @@ static val buf_strm_put_byte(val stream, int b)
static int buf_strm_get_byte_callback(mem_t *ctx)
{
- val self = lit("get-byte");
struct buf_strm *s = coerce(struct buf_strm *, ctx);
struct buf *b = us_buf_handle(s->buf);
- cnum p = buf_check_index(b, s->pos, self);
- s->pos = num(p + 1);
- return (p >= c_num(b->len, self)) ? EOF : b->data[p];
+ return (s->pos >= b->len) ? EOF : b->data[s->pos++];
}
static val buf_strm_get_char(val stream)
@@ -1173,22 +1199,22 @@ static val buf_strm_unget_char(val stream, val ch)
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);
+ ucnum pos = s->pos;
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) {
+ if (convert(size_t, bend - bu.ptr) > pos) {
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++;
+ b->data[--pos] = *bu.ptr++;
- s->pos = unum(index);
+ s->pos = pos;
return ch;
}
@@ -1198,16 +1224,16 @@ static val buf_strm_unget_byte(val stream, int byte)
val self = lit("unget-byte");
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
struct buf *b = us_buf_handle(s->buf);
- cnum p = c_num(s->pos, self);
+ ucnum pos = s->pos;
- if (p <= 0) {
+ if (pos <= 0) {
uw_throwf(file_error_s,
lit("~a: cannot push back past start of stream ~s"),
self, stream, nao);
}
- b->data[--p] = byte;
- s->pos = num(p);
+ b->data[--pos] = byte;
+ s->pos = pos;
return num_fast(byte);
}
@@ -1222,12 +1248,12 @@ static ucnum buf_strm_fill_buf(val stream, mem_t *ptr, ucnum len, ucnum pos)
if (pos >= len) {
return len;
} else {
- size_t index = c_unum(s->pos, self);
size_t room = len - pos;
- size_t avail = c_u(b->size) - index;
+ size_t blen = b->size == BUF_BORROWED ? b->len : b->size;
+ size_t avail = blen - s->pos;
size_t copy = min(room, avail);
- memcpy(ptr + pos, b->data + index, copy);
- s->pos = plus(s->pos, unum(copy));
+ memcpy(ptr + pos, b->data + s->pos, copy);
+ s->pos += copy;
return pos + copy;
}
}
@@ -1238,31 +1264,35 @@ static val buf_strm_seek(val stream, val offset, enum strm_whence whence)
val self = lit("seek-stream");
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
struct buf *b = us_buf_handle(s->buf);
- val npos;
+ cnum off = c_num(offset, self);
+ ucnum npos;
+ ucnum from;
switch (whence) {
case strm_start:
- npos = offset;
+ from = 0;
break;
case strm_cur:
- if (offset == zero)
- return s->pos;
- npos = plus(s->pos, offset);
+ if (off == 0)
+ return unum(s->pos);
+ from = s->pos;
break;
case strm_end:
- npos = plus(b->len, offset);
+ from = b->len;
break;
default:
internal_error("invalid whence value");
}
+ npos = from + off;
- if (minusp(npos))
- uw_throwf(file_error_s, lit("~a: cannot seek to negative position ~s"),
- self, npos, nao);
+ if ((off >= 0 && npos < from) ||
+ (off < 0 && npos > from))
+ uw_throwf(file_error_s, lit("~a: overflow in seeking ~s bytes from ~s"),
+ self, offset, unum(from), nao);
- if (gt(npos, b->len))
- buf_set_length(s->buf, npos, zero);
+ if (npos > b->len)
+ buf_set_length(s->buf, unum(npos), zero);
s->pos = npos;
return t;
@@ -1271,19 +1301,15 @@ static val buf_strm_seek(val stream, val offset, enum strm_whence whence)
static val buf_strm_truncate(val stream, val len)
{
val self = lit("truncate-stream");
+ ucnum blen = buf_check_len(len, self);
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
struct buf *b = us_buf_handle(s->buf);
- if (ge(len, s->pos)) {
- buf_set_length(s->buf, len, zero);
- } else if (minusp(len)) {
- uw_throwf(file_error_s, lit("~a: negative length~s specified"),
- self, len, nao);
+ if (blen >= s->pos) {
+ buf_do_set_len(s->buf, b, blen, nil, self);
} else {
- cnum p = c_num(s->pos, self);
- cnum l = c_num(len, self);
- buf_set_length(s->buf, s->pos, zero);
- memset(b->data + l, 0, p - l);
+ buf_do_set_len(s->buf, b, s->pos, nil, self);
+ memset(b->data + blen, 0, s->pos - blen);
}
return t;
@@ -1319,12 +1345,12 @@ static val buf_strm_get_error(val stream)
{
struct buf_strm *s = coerce(struct buf_strm *, stream->co.handle);
struct buf *b = us_buf_handle(s->buf);
- return ge(s->pos, b->len);
+ return tnil(s->pos >= b->len);
}
static val buf_strm_get_error_str(val stream)
{
- return errno_to_string(buf_strm_get_error(stream));
+ return buf_strm_get_error(stream) ? lit("eof") : lit("no error");
}
static struct strm_ops buf_strm_ops =
@@ -1378,7 +1404,7 @@ val make_buf_stream(val buf_opt)
strm_base_init(&s->a);
utf8_decoder_init(&s->ud);
s->buf = nil;
- s->pos = zero;
+ s->pos = 0;
s->is_byte_oriented = 0;
stream = cobj(coerce(mem_t *, s), stream_cls, &buf_strm_ops.cobj_ops);
s->buf = buf;
@@ -1397,7 +1423,7 @@ void buf_swap32(val buf)
{
val self = lit("buf-swap32");
struct buf *b = buf_handle(buf, self);
- mem_t *data = b->data, *end = data + c_num(b->len, self);
+ mem_t *data = b->data, *end = data + b->len;
for (; data + 3 < end; data += 4) {
u32_t sw32 = *coerce(u32_t *, data);
@@ -1413,7 +1439,7 @@ static val buf_str(val str, val null_term)
size_t sz;
val nt = default_null_arg(null_term);
unsigned char *u8 = utf8_dup_to_buf(c_str(str, self), &sz, nt != nil);
- return make_owned_buf(unum(sz), u8);
+ return make_owned_buf(sz, u8, self);
}
static val str_buf(val buf, val null_term)
@@ -1421,8 +1447,8 @@ static val str_buf(val buf, val null_term)
val self = lit("str-buf");
struct buf *b = buf_handle(buf, self);
val nt = default_null_arg(null_term);
- size_t blen = c_unum(b->len, self);
- size_t len = (nt && blen > 0 && !b->data[blen-1]) ? blen - 1 : blen;
+ size_t blen = b->len;
+ size_t len = (nt && blen > 0 && !b->data[blen - 1]) ? blen - 1 : blen;
wchar_t *str = utf8_dup_from_buf(coerce(const char *, b->data), len);
return string_own(str);
}
@@ -1451,7 +1477,7 @@ static val buf_int(val num)
mem_t *data = chk_malloc(bufsize);
data[0] = 0;
mp_to_unsigned_bin(m, data + (bufsize - numsize));
- return make_owned_buf(unum(bufsize), data);
+ return make_owned_buf(bufsize, data, self);
}
default:
uw_throwf(type_error_s, lit("~a: ~s isn't an integer or character"),
@@ -1476,7 +1502,7 @@ static val buf_uint(val num)
size_t size = mp_unsigned_bin_size(m);
mem_t *data = chk_malloc(size);
mp_to_unsigned_bin(m, data);
- return make_owned_buf(unum(size), data);
+ return make_owned_buf(size, data, self);
}
}
uw_throwf(type_error_s, lit("~a: ~s isn't a non-negative integer"),
@@ -1491,19 +1517,19 @@ static val int_buf(val buf)
{
val self = lit("int-buf");
struct buf *b = buf_handle(buf, self);
- ucnum size = c_unum(b->len, self);
+ ucnum size = b->len;
val ubn = make_bignum();
mp_err mpe = mp_read_unsigned_bin(mp(ubn), b->data, size);
if (mpe != MP_OKAY)
do_mp_error(self, mpe);
- return sign_extend(normalize(ubn), mul(b->len, num_fast(8)));
+ return sign_extend(normalize(ubn), unum(b->len * 8));
}
static val uint_buf(val buf)
{
val self = lit("uint-buf");
struct buf *b = buf_handle(buf, self);
- ucnum size = c_unum(b->len, self);
+ ucnum size = b->len;
val ubn = make_bignum();
mp_err mpe = mp_read_unsigned_bin(mp(ubn), b->data, size);
if (mpe != MP_OKAY)
@@ -1519,7 +1545,7 @@ static val buf_compress(val buf, val level_opt)
val level = default_arg(level_opt, negone);
int lev = c_int(level, self);
struct buf *b = buf_handle(buf, self);
- ucnum size = c_unum(b->len, self);
+ ucnum size = b->len;
uLong bound = compressBound(size), zsize = bound;
mem_t *zdata = chk_malloc(bound);
@@ -1534,14 +1560,14 @@ static val buf_compress(val buf, val level_opt)
}
zdata = chk_realloc(zdata, zsize);
- return make_owned_buf(unum(zsize), zdata);
+ return make_owned_buf(zsize, zdata, self);
}
static val buf_decompress(val buf)
{
val self = lit("buf-decompress");
struct buf *b = buf_handle(buf, self);
- ucnum zsize = c_unum(b->len, self);
+ ucnum zsize = b->len;
uLong zsz10 = 10 * zsize;
uLong size = if3(zsz10 > zsize, zsz10, convert(uLong, -1));
mem_t *data = chk_malloc(size);
@@ -1550,7 +1576,7 @@ static val buf_decompress(val buf)
switch (uncompress(data, &size, b->data, zsize)) {
case Z_OK:
data = chk_realloc(data, size);
- return make_owned_buf(unum(size), data);
+ return make_owned_buf(size, data, self);
case Z_BUF_ERROR:
if (size == convert(uLong, -1))
break;
@@ -1593,14 +1619,14 @@ static val str_compress(val str, val level_opt)
}
zdata = chk_realloc(zdata, zsize);
- return make_owned_buf(unum(zsize), zdata);
+ return make_owned_buf(zsize, zdata, self);
}
static val str_decompress(val buf)
{
val self = lit("str-decompress");
struct buf *b = buf_handle(buf, self);
- ucnum zsize = c_unum(b->len, self);
+ ucnum zsize = b->len;
uLong zsz10 = 10 * zsize;
uLong size = if3(zsz10 > zsize, zsz10, convert(uLong, -1));
mem_t *data = chk_malloc(size);
@@ -1642,7 +1668,7 @@ val buf_ash(val buf, val bits)
val self = lit("buf-ash");
cnum b = c_num(bits, self);
struct buf *bh = buf_handle(buf, self);
- ucnum len = c_unum(bh->len, self);
+ ucnum len = bh->len;
if (b == 0) {
return buf;
@@ -1721,7 +1747,7 @@ val buf_fash(val buf, val bits)
val self = lit("buf-ash");
cnum b = c_num(bits, self);
struct buf *bh = buf_handle(buf, self);
- ucnum len = c_unum(bh->len, self);
+ const ucnum len = bh->len;
if (b == 0 || len == 0) {
return buf;
@@ -1729,7 +1755,8 @@ val buf_fash(val buf, val bits)
ucnum bytes = b / 8;
if (bytes >= len) {
- return make_buf(bh->len, zero, bh->len);
+ val len = unum(bh->len);
+ return make_buf(len, zero, len);
} else {
ucnum r = b % 8;
unsigned acc = 0;
@@ -1753,7 +1780,8 @@ val buf_fash(val buf, val bits)
ucnum bytes = (-b) / 8;
if (bytes >= len) {
- return make_buf(bh->len, zero, bh->len);
+ val len = unum(bh->len);
+ return make_buf(len, zero, len);
} else {
ucnum r = (-b) % 8;
unsigned acc = 0;
@@ -1783,13 +1811,13 @@ val buf_and(val bufa, val bufb)
val self = lit("buf-and");
struct buf *ab = buf_handle(bufa, self);
struct buf *bb = buf_handle(bufb, self);
- ucnum la = c_unum(ab->len, self);
- ucnum lb = c_unum(bb->len, self);
+ ucnum la = ab->len;
+ ucnum lb = bb->len;
if (la == 0) {
- return make_buf(bb->len, zero, bb->len);
+ return make_buf(unum(bb->len), zero, unum(bb->len));
} else if (lb == 0) {
- return make_buf(ab->len, zero, ab->len);
+ return make_buf(unum(ab->len), zero, unum(ab->len));
} else if (la < lb) {
return buf_and(bufb, bufa);
} else {
@@ -1812,8 +1840,8 @@ val buf_test(val bufa, val bufb)
val self = lit("buf-test");
struct buf *ab = buf_handle(bufa, self);
struct buf *bb = buf_handle(bufb, self);
- ucnum la = c_unum(ab->len, self);
- ucnum lb = c_unum(bb->len, self);
+ ucnum la = ab->len;
+ ucnum lb = bb->len;
if (la == 0 || lb == 0 ) {
return nil;
@@ -1837,8 +1865,8 @@ val buf_or(val bufa, val bufb)
val self = lit("buf-or");
struct buf *ab = buf_handle(bufa, self);
struct buf *bb = buf_handle(bufb, self);
- ucnum la = c_unum(ab->len, self);
- ucnum lb = c_unum(bb->len, self);
+ ucnum la = ab->len;
+ ucnum lb = bb->len;
if (la == 0) {
return bufb;
@@ -1866,8 +1894,8 @@ val buf_xor(val bufa, val bufb)
val self = lit("buf-xor");
struct buf *ab = buf_handle(bufa, self);
struct buf *bb = buf_handle(bufb, self);
- ucnum la = c_unum(ab->len, self);
- ucnum lb = c_unum(bb->len, self);
+ ucnum la = ab->len;
+ ucnum lb = bb->len;
if (la == 0) {
return bufb;
@@ -1894,7 +1922,7 @@ val buf_not(val buf)
{
val self = lit("buf-not");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self);
+ ucnum l = b->len;
if (l == 0) {
return buf;
@@ -1915,7 +1943,7 @@ val buf_trunc(val buf, val bits)
val self = lit("buf-trunc");
cnum b = c_num(bits, self);
struct buf *bh = buf_handle(buf, self);
- ucnum l = c_unum(bh->len, self);
+ ucnum l = bh->len;
if (b <= 0) {
return make_buf(zero, nil, zero);
@@ -1942,7 +1970,7 @@ val buf_bitset(val buf)
{
val self = lit("buf-bitset");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self), i, j;
+ ucnum l = b->len, i, j;
list_collect_decl (out, ptail);
for (i = l - 1, j = 0; i != convert(ucnum, -1); --i, j++) {
@@ -1975,7 +2003,7 @@ val buf_bit(val buf, val bit)
{
val self = lit("buf-bit");
struct buf *bh = buf_handle(buf, self);
- ucnum l = c_unum(bh->len, self);
+ ucnum l = bh->len;
cnum b = c_num(bit, self);
if (b < 0) {
@@ -1995,7 +2023,7 @@ val buf_zero_p(val buf)
{
val self = lit("buf-zero-p");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self), i;
+ ucnum l = b->len, i;
ucnum *ucdata = coerce(ucnum *, b->data);
for (i = 0; i < l / sizeof (ucnum); i++) {
@@ -2014,7 +2042,7 @@ val buf_count_ones(val buf)
{
val self = lit("buf-count-ones");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self), i;
+ ucnum l = b->len, i;
ucnum *ucdata = coerce(ucnum *, b->data);
ucnum total[2] = { 0, 0 };
@@ -2079,7 +2107,7 @@ val buf_binary_width(val buf)
{
val self = lit("buf-bit-width");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self), i;
+ ucnum l = b->len, i;
ucnum *ucdata = coerce(ucnum *, b->data);
ucnum zeros[2] = { 0, 0 };
int found = 0;
@@ -2167,7 +2195,7 @@ val buf_xor_pattern(val buf, val pat)
{
val self = lit("buf-xor-pattern");
struct buf *b = buf_handle(buf, self);
- ucnum l = c_unum(b->len, self), pl;
+ ucnum l = b->len, pl;
mem_t *p = 0, *fr = 0;
unsigned char pbuf[SIZEOF_PTR] = { 0 };
int left = 0;