summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-02-26 22:34:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-02-26 22:34:14 -0800
commit875c0c2d16fbcaa61bfc46da58533ab0890bf513 (patch)
treedcc2c644127dc38c3b2a6b4cfda12491c8368399 /arith.c
parenta9e1bec854f6c0343dfb2cb32879cdb31d84f209 (diff)
downloadtxr-875c0c2d16fbcaa61bfc46da58533ab0890bf513.tar.gz
txr-875c0c2d16fbcaa61bfc46da58533ab0890bf513.tar.bz2
txr-875c0c2d16fbcaa61bfc46da58533ab0890bf513.zip
Functions for converting between buffers and integers.
These functions convert between positive integers, and fixed-size memory buffers representing pure binary numbers in big endian byte order. This functionality will be used in some upcoming networking code. * arith.c (num_from_buffer, num_to_buffer): New functions. * arith.h (num_from_buffer, num_to_buffer): Declared. * mpi/mpi.c (mp_to_unsigned_buf): New function. * mpi/mpi.h (mp_to_unsigned_buf): Declared.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arith.c b/arith.c
index 497aefa7..ecb3e03e 100644
--- a/arith.c
+++ b/arith.c
@@ -90,6 +90,37 @@ val bignum_from_uintptr(uint_ptr_t u)
return n;
}
+val num_from_buffer(mem_t *buf, int bytes)
+{
+ val n = make_bignum();
+ mp_read_unsigned_bin(mp(n), buf, bytes);
+ return normalize(n);
+}
+
+int num_to_buffer(val num, mem_t *buf, int bytes)
+{
+ switch (type(num)) {
+ case CHR: case NUM:
+ {
+ cnum n = coerce(cnum, num) >> TAG_SHIFT;
+ mem_t *ptr = buf + bytes;
+
+ for (; n != 0; n >>= 8) {
+ if (ptr == buf)
+ return 0;
+ *--ptr = n & 0xff;
+ }
+ while (ptr > buf)
+ *--ptr = 0;
+ }
+ return 1;
+ case BGNUM:
+ return mp_to_unsigned_buf(mp(num), buf, bytes) == MP_OKAY ? 1 : 0;
+ default:
+ type_mismatch(lit("~s is not an integer"), num, nao);
+ }
+}
+
#if HAVE_DOUBLE_INTPTR_T
static val bignum_dbl_ipt(double_intptr_t di)