summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--bits.c77
-rw-r--r--bits.h42
3 files changed, 120 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 727bda5b..528b099d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,7 +14,7 @@ INCLUDES = $(DBUS_CFLAGS)
endif
bin_PROGRAMS = $(BUILD_PROGS) sirfmon
-check_PROGRAMS = gpsmm_test
+check_PROGRAMS = gpsmm_test bits
bin_SCRIPTS = gpsprof gpsfake
#
diff --git a/bits.c b/bits.c
new file mode 100644
index 00000000..df8275f6
--- /dev/null
+++ b/bits.c
@@ -0,0 +1,77 @@
+/* test harness for bits.h */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bits.h"
+
+int main (int argc, char *argv[])
+
+{
+ unsigned char buf[80];
+ union int_float i_f;
+ union long_double l_d;
+ char sb1,sb2;
+ unsigned char ub1,ub2;
+ short sw1,sw2;
+ unsigned short uw1,uw2;
+ int sl1,sl2;
+ unsigned int ul1,ul2;
+ long long sL1,sL2;
+ unsigned long long uL1,uL2;
+ float f1;
+ double d1;
+
+ memcpy(buf,"\x01\x02\x03\x04\x05\x06\x07\x08",8);
+ memcpy(buf+8,"\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8",8);
+ memcpy(buf+16,"\x40\x09\x21\xfb\x54\x44\x2d\x18",8);
+ memcpy(buf+24,"\x40\x49\x0f\xdb",4);
+
+ sb1 = getsb(0);
+ sb2 = getsb(8);
+ ub1 = getub(0);
+ ub2 = getub(8);
+ sw1 = getsw(0);
+ sw2 = getsw(8);
+ uw1 = getuw(0);
+ uw2 = getuw(8);
+ sl1 = getsl(0);
+ sl2 = getsl(8);
+ ul1 = getul(0);
+ ul2 = getul(8);
+ sL1 = getsL(0);
+ sL2 = getsL(8);
+ uL1 = getuL(0);
+ uL2 = getuL(8);
+ f1 = getf(24);
+ d1 = getd(16);
+
+ printf("getsb: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)sb1, (unsigned long long)sb2,
+ (unsigned long long)getsb(0), (unsigned long long)getsb(8));
+ printf("getub: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)ub1, (unsigned long long)ub2,
+ (unsigned long long)getub(0), (unsigned long long)getub(8));
+ printf("getsw: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)sw1, (unsigned long long)sw2,
+ (unsigned long long)getsw(0), (unsigned long long)getsw(8));
+ printf("getuw: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)uw1, (unsigned long long)uw2,
+ (unsigned long long)getuw(0), (unsigned long long)getuw(8));
+ printf("getsl: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)sl1, (unsigned long long)sl2,
+ (unsigned long long)getsl(0), (unsigned long long)getsl(8));
+ printf("getul: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)ul1, (unsigned long long)ul2,
+ (unsigned long long)getul(0), (unsigned long long)getul(8));
+ printf("getsL: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)sL1, (unsigned long long)sL2,
+ (unsigned long long)getsL(0), (unsigned long long)getsL(8));
+ printf("getuL: %016llx %016llx %016llx %016llx\n",
+ (unsigned long long)uL1, (unsigned long long)uL2,
+ (unsigned long long)getuL(0), (unsigned long long)getuL(8));
+ printf("getf: %f %f\n", f1, getf(24));
+ printf("getd: %.16f %.16f\n", d1, getd(16));
+
+ exit(0);
+}
diff --git a/bits.h b/bits.h
new file mode 100644
index 00000000..1dcea658
--- /dev/null
+++ b/bits.h
@@ -0,0 +1,42 @@
+/*
+ * bits.h - extract binary data from message buffer
+ *
+ * these macros extract bytes, words, longwords, floats or doubles from
+ * a message that contains these items in MSB-first byte order.
+ *
+ * the macros access a local buffer named "buf" which must be declared
+ * as unsigned char buf[SIZE];
+ *
+ * assumptions:
+ * char is 8 bits, short is 16 bits, int is 32 bits, long long is 64 bits,
+ * float is 32 bits IEEE754, double is 64 bits IEEE754.
+ *
+ * it would be possible to use types like int16_t from header files to enforce
+ * these assumptions, but splint does not understand those and will scream.
+ * also, using such explicitly sized types usually causes warnings at many
+ * other places in a program (like when calling library routines). we will
+ * need to consider this again when we want to port to an architecture which
+ * implements differently sized types. it looks like 64bit systems with
+ * gcc are OK.
+ */
+
+union int_float {
+ int i;
+ float f;
+};
+
+union long_double {
+ long long l;
+ double d;
+};
+
+#define getsb(off) ((char)buf[off])
+#define getub(off) (buf[off])
+#define getsw(off) ((short)(((unsigned)getub(off) << 8) | (unsigned)getub(off+1)))
+#define getuw(off) ((unsigned short)(((unsigned)getub(off) << 8) | (unsigned)getub(off+1)))
+#define getsl(off) ((int)(((unsigned)getuw(off) << 16) | getuw(off+2)))
+#define getul(off) ((unsigned int)(((unsigned)getuw(off) << 16) | getuw(off+2)))
+#define getsL(off) ((long long)(((unsigned long long)getul(off) << 32) | getul(off+4)))
+#define getuL(off) ((unsigned long long)(((unsigned long long)getul(off) << 32) | getul(off+4)))
+#define getf(off) (i_f.i = getsl(off), i_f.f)
+#define getd(off) (l_d.l = getsL(off), l_d.d)