summaryrefslogtreecommitdiffstats
path: root/buf.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-21 21:26:19 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-21 21:26:19 -0700
commitb1726e0878b679508dda20166b04cac12213729b (patch)
tree208cc17ff9ebb6ce5862341675cf6d27749a1724 /buf.c
parentb4d9e01b4c68a995d39f7c01c43ba2aed02c968b (diff)
downloadtxr-b1726e0878b679508dda20166b04cac12213729b.tar.gz
txr-b1726e0878b679508dda20166b04cac12213729b.tar.bz2
txr-b1726e0878b679508dda20166b04cac12213729b.zip
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.
Diffstat (limited to 'buf.c')
-rw-r--r--buf.c134
1 files changed, 117 insertions, 17 deletions
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)