From b1726e0878b679508dda20166b04cac12213729b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku <kaz@kylheku.com> Date: Fri, 21 Apr 2017 21:26:19 -0700 Subject: Buffers implementation, part three: get functions. * arith.c (unum): New function. * arith.h (unum): Declared. * buf.c (buf_get_bytes): New static function. (buf_get_i8, buf_get_u8, buf_get_i16, buf_get_u16, buf_get_i32, buf_get_u32, buf_get_i64, buf_get_u64, buf_get_char, buf_get_uchar, buf_get_short, buf_get_ushort, buf_get_int, buf_get_uint, buf_get_long, buf_get_ulong, buf_get_double): Stubs implemented. --- buf.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 17 deletions(-) (limited to 'buf.c') diff --git a/buf.c b/buf.c index feba34b7..b57e7507 100644 --- a/buf.c +++ b/buf.c @@ -354,85 +354,185 @@ val buf_put_double(val buf, val pos, val num) return num; } +static void buf_get_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) +{ + struct buf *b = buf_handle(buf, self); + cnum p = buf_check_index(pos, self); + cnum e = p + size; + cnum l = c_num(b->len); + + if (e >= l || e < 0) + uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao); + + memcpy(ptr, b->data + p, size); +} + #if HAVE_I8 val buf_get_i8(val buf, val pos) { - return nil; + val self = lit("buf-get-i8"); + struct buf *b = buf_handle(buf, self); + cnum p = buf_check_index(pos, self); + if (p >= c_num(b->len)) + uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao); + return num_fast((i8_t) b->data[p]); } + val buf_get_u8(val buf, val pos) { - return nil; + val self = lit("buf-get-u8"); + struct buf *b = buf_handle(buf, self); + cnum p = buf_check_index(pos, self); + if (p >= c_num(b->len)) + uw_throwf(error_s, lit("~a: attempted read past buffer end"), self, nao); + return num_fast((u8_t) b->data[p]); } #endif #if HAVE_I16 val buf_get_i16(val buf, val pos) { - return nil; + val self = lit("buf-get-i16"); + i16_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return num_fast(n); } + val buf_get_u16(val buf, val pos) { - return nil; + val self = lit("buf-get-u16"); + u16_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return num_fast(n); } #endif #if HAVE_I32 val buf_get_i32(val buf, val pos) { - return nil; + val self = lit("buf-get-i32"); + i32_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return num(n); } + val buf_get_u32(val buf, val pos) { - return nil; + val self = lit("buf-get-u32"); + u32_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return unum(n); } #endif #if HAVE_I64 val buf_get_i64(val buf, val pos) { - return nil; + val self = lit("buf-get-i64"); + i64_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + + if (sizeof (i64_t) <= sizeof (cnum)) { + return num(n); + } else { + val high = num(n >> 32); + val low = unum(n & 0xFFFFFFFF); + return logior(ash(high, num_fast(32)), low); + } } + val buf_get_u64(val buf, val pos) { - return nil; + val self = lit("buf-get-u64"); + u64_t n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + + if (sizeof (u64_t) <= sizeof (uint_ptr_t)) { + return unum(n); + } else { + val high = unum(n >> 32); + val low = unum(n & 0xFFFFFFFF); + return logior(ash(high, num_fast(32)), low); + } } #endif val buf_get_char(val buf, val pos) { - return nil; +#if CHAR_MAX == UCHAR_MAX + return buf_get_u8(buf, pos); +#else + return buf_get_i8(buf, pos); +#endif } + val buf_get_uchar(val buf, val pos) { - return nil; + return buf_get_u8(buf, pos); } + val buf_get_short(val buf, val pos) { - return nil; + val self = lit("buf-get-short"); + short n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); +#if SIZEOF_SHORT < SIZEOF_PTR + return num_fast(n); +#else + return num(n); +#endif } + val buf_get_ushort(val buf, val pos) { - return nil; + val self = lit("buf-get-ushort"); + unsigned short n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); +#if SIZEOF_SHORT < SIZEOF_PTR + return num_fast(n); +#else + return unum(n); +#endif } + val buf_get_int(val buf, val pos) { - return nil; + val self = lit("buf-get-int"); + int n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return num(n); } + val buf_get_uint(val buf, val pos) { - return nil; + val self = lit("buf-get-uint"); + unsigned n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return unum(n); } + val buf_get_long(val buf, val pos) { - return nil; + val self = lit("buf-get-long"); + long n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return num(n); } + val buf_get_ulong(val buf, val pos) { - return nil; + val self = lit("buf-get-long"); + unsigned long n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return unum(n); } + val buf_get_double(val buf, val pos) { - return nil; + val self = lit("buf-get-double"); + double n; + buf_get_bytes(buf, pos, coerce(mem_t *, &n), sizeof n, self); + return flo(n); } val buf_print(val buf, val stream_in) -- cgit v1.2.3