aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2020-09-11 01:19:11 +0100
committerTomasz Kramkowski <tk@the-tk.com>2020-09-11 01:26:20 +0100
commit8d1175ab41dd64de007628def55e8c4b19c7538c (patch)
treef878cd630d60c3ba75eb840037ddc10b394befed
parentc5aea8daee8cfa775cd3979dca3e7401f517252f (diff)
downloadpack-8d1175ab41dd64de007628def55e8c4b19c7538c.tar.gz
pack-8d1175ab41dd64de007628def55e8c4b19c7538c.tar.xz
pack-8d1175ab41dd64de007628def55e8c4b19c7538c.zip
Implement double deserialisation.
-rw-r--r--unpack.c10
-rw-r--r--unpack_test.c14
2 files changed, 23 insertions, 1 deletions
diff --git a/unpack.c b/unpack.c
index 8f6880b..5b99211 100644
--- a/unpack.c
+++ b/unpack.c
@@ -52,6 +52,7 @@ static type convert_ieee754b##total(uintmax_t b) \
}
GEN_CONV_IEEE754B(float, 32, 8, 23)
+GEN_CONV_IEEE754B(double, 64, 11, 52)
static uintmax_t read_val(unsigned char *buf, size_t size, enum endian e)
{
@@ -90,8 +91,9 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...)
long long *q;
unsigned long long *Q;
float *f;
+ double *d;
} arg;
- union { uintmax_t u; intmax_t s; float f; } val;
+ union { uintmax_t u; intmax_t s; float f; double d; } val;
tr_debug("i: %d, fmt[i]: %c", i, fmt[i]);
if (isdigit(fmt[i])) {
unsigned long long c;
@@ -124,6 +126,7 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...)
case 'q': arg.q = va_arg(ap, long long *); break;
case 'Q': arg.Q = va_arg(ap, unsigned long long *); break;
case 'f': arg.f = va_arg(ap, float *); break;
+ case 'd': arg.d = va_arg(ap, double *); break;
case 'x': break;
return PACK_FMTINVAL;
}
@@ -144,6 +147,10 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...)
float f = convert_ieee754b32(val.u);
val.f = f;
tr_debug("val.f: %f", val.f);
+ } else if (fmt[i] == 'd') {
+ double d = convert_ieee754b64(val.u);
+ val.d = d;
+ tr_debug("val.d: %f", val.d);
} else if (sign) {
intmax_t vals;
if (!(val.u & (UINTMAX_C(1) << (s * 8 - 1)))) {
@@ -168,6 +175,7 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...)
case 'q': arg.q[j] = val.s; break;
case 'Q': arg.Q[j] = val.u; break;
case 'f': arg.f[j] = val.f; break;
+ case 'd': arg.d[j] = val.d; break;
}
}
skip:
diff --git a/unpack_test.c b/unpack_test.c
index 66d2117..1d7ea4c 100644
--- a/unpack_test.c
+++ b/unpack_test.c
@@ -50,6 +50,20 @@ TEST(simple0_float, "simple unpack float")
return true;
}
+TEST(simple0_double, "simple unpack double")
+{
+ double v[1] = { __LINE__ };
+
+ CHECK_UNPACK(DATA(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), "d", &v);
+ CHECK_EQUAL("f", v[0], 0.0f);
+ CHECK_UNPACK(DATA(0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), "d", &v);
+ CHECK_EQUAL("f", v[0], 1.0f);
+ CHECK_UNPACK(DATA(0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), "d", &v);
+ CHECK_EQUAL("f", v[0], 8.0f);
+
+ return true;
+}
+
int main(void)
{
extern struct test __start_tests, __stop_tests;