summaryrefslogtreecommitdiff
path: root/bits.h
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2005-06-10 21:23:02 +0000
committerEric S. Raymond <esr@thyrsus.com>2005-06-10 21:23:02 +0000
commit5e9ad018406fbfdd3a21e191f3c1aafa8ec2c108 (patch)
tree47ded8f037b7e8164c05da92161c89a2daf7d08a /bits.h
parentaf369699cfdf433cc8114565603a24fa2d09e3ea (diff)
downloadgpsd-5e9ad018406fbfdd3a21e191f3c1aafa8ec2c108.tar.gz
New version of bits.h with fixed-width types for cross-architecture portability.
Also, the bit-getter macros from zodiac.c now live here.
Diffstat (limited to 'bits.h')
-rw-r--r--bits.h46
1 files changed, 25 insertions, 21 deletions
diff --git a/bits.h b/bits.h
index 5554a3d7..18bcfebf 100644
--- a/bits.h
+++ b/bits.h
@@ -1,21 +1,17 @@
/*
* bits.h - extract binary data from message buffer
- * * These macros extract bytes, words, longwords, floats or doubles from
+ *
+ * These macros extract bytes, words, longwords, floats or doubles from
* a message that contains these items in MSB-first byte order.
* By defining the GET_ORIGIN and PUT_ORIGIN macros, it's possible to
* change the origin of the indexing.
*
- * assumptions:
+ * 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. Noth 32- and 64-bit systems with
- * gcc are OK.
+ * The use of fixed-length types in the casts enforces these.
+ * Both 32- and 64-bit systems with gcc are OK with this set.
*/
union int_float {
@@ -31,22 +27,30 @@ union long_double {
#ifndef GET_ORIGIN
#define GET_ORIGIN 0
#endif
-
-#define getsb(buf, off) ((char)buf[GET_ORIGIN+(off)])
-#define getub(buf, off) (buf[GET_ORIGIN+(off)])
-#define getsw(buf, off) ((short)(((unsigned)getub(buf, off) << 8) | (unsigned)getub(buf, off+1)))
-#define getuw(buf, off) ((unsigned short)(((unsigned)getub(buf, off) << 8) | (unsigned)getub(buf, off+1)))
-#define getsl(buf, off) ((int)(((unsigned)getuw(buf, off) << 16) | getuw(buf, off+2)))
-#define getul(buf, off) ((unsigned int)(((unsigned)getuw(buf, off) << 16) | getuw(buf, off+2)))
-#define getsL(buf, off) ((long long)(((unsigned long long)getul(buf, off) << 32) | getul(buf, off+4)))
-#define getuL(buf, off) ((unsigned long long)(((unsigned long long)getul(buf, off) << 32) | getul(buf, off+4)))
-#define getf(buf, off) (i_f.i = getsl(buf, off), i_f.f)
-#define getd(buf, off) (l_d.l = getsL(buf, off), l_d.d)
-
#ifndef PUT_ORIGIN
#define PUT_ORIGIN 0
#endif
+/* SiRF and most other GPS protocols use big-endian (network byte order) */
+#define getsb(buf, off) ((int8_t)buf[GET_ORIGIN+(off)])
+#define getub(buf, off) ((u_int8_t)buf[GET_ORIGIN+(off)])
+#define getsw(buf, off) ((int16_t)(((u_int16_t)getub(buf, off) << 8) | (u_int16_t)getub(buf, off+1)))
+#define getuw(buf, off) ((u_int16_t)(((u_int16_t)getub(buf, off) << 8) | (u_int16_t)getub(buf, off+1)))
+#define getsl(buf, off) ((int32_t)(((u_int16_t)getuw(buf, off) << 16) | getuw(buf, off+2)))
+#define getul(buf, off) ((u_int32_t)(((u_int16_t)getuw(buf, off) << 16) | getuw(buf, off+2)))
+#define getsL(buf, off) ((int64_t)(((u_int64_t)getul(buf, off) << 32) | getul(buf, off+4)))
+#define getuL(buf, off) ((u_int64_t)(((u_int64_t)getul(buf, off) << 32) | getul(buf, off+4)))
+#define getf(buf, off) (i_f.i = getsl(buf, off), i_f.f)
+#define getd(buf, off) (l_d.l = getsL(buf, off), l_d.d)
+
#define putbyte(buf,off,b) {buf[PUT_ORIGIN+(off)] = (unsigned char)(b);}
#define putword(buf,off,w) {putbyte(buf,off,(w) >> 8); putbyte(buf,off+1,w);}
#define putlong(buf,off,l) {putword(buf,off,(l) >> 16); putword(buf,off+2,l);}
+
+/* Zodiac protocol description uses 1-origin indexing by little-endian word */
+#define getword(n) ( (session->outbuffer[2*(n)-2]) \
+ | (session->outbuffer[2*(n)-1] << 8))
+#define getlong(n) ( (session->outbuffer[2*(n)-2]) \
+ | (session->outbuffer[2*(n)-1] << 8) \
+ | (session->outbuffer[2*(n)+0] << 16) \
+ | (session->outbuffer[2*(n)+1] << 24))