diff options
-rw-r--r-- | common.c | 20 | ||||
-rw-r--r-- | common.h | 6 | ||||
-rw-r--r-- | pack.c | 32 | ||||
-rw-r--r-- | pack.h | 21 | ||||
-rw-r--r-- | unpack.c | 36 |
5 files changed, 68 insertions, 47 deletions
@@ -7,20 +7,20 @@ #include "common.h" #include "pack.h" -size_t getsize(char c) +size_t getsize(enum pack_type t) { - switch (c) { - case 'b': case 'B': - case 'x': + switch (t) { + case PACK_TYPE_SCHAR: case PACK_TYPE_UCHAR: + case PACK_TYPE_PADDING: return 1; - case 'h': case 'H': - case 'i': case 'I': + case PACK_TYPE_SHORT: case PACK_TYPE_USHORT: + case PACK_TYPE_INT: case PACK_TYPE_UINT: return 2; - case 'l': case 'L': - case 'f': + case PACK_TYPE_LONG: case PACK_TYPE_ULONG: + case PACK_TYPE_FLOAT: return 4; - case 'q': case 'Q': - case 'd': + case PACK_TYPE_LLONG: case PACK_TYPE_ULLONG: + case PACK_TYPE_DOUBLE: return 8; default: return (size_t)-1; } @@ -8,6 +8,8 @@ #include <limits.h> #include <stddef.h> +#include "pack.h" + #define BITMASK(n) (UINTMAX_MAX >> (sizeof (uintmax_t) * CHAR_BIT - n)) #ifndef PRIuSIZE @@ -22,8 +24,6 @@ #endif #endif -enum endian { BIG, LITTLE }; - -size_t getsize(char c); +size_t getsize(enum pack_type t); #endif // !PACK_COMMON_H @@ -12,15 +12,15 @@ #include "pack.h" #include "trace.h" -static void write_val(unsigned char *buf, size_t size, enum endian e, uintmax_t val) +static void write_val(unsigned char *buf, size_t size, enum pack_endian e, uintmax_t val) { for (size_t i = 0; i < size; i++) - buf[i] = (val >> (e == LITTLE ? i : size - i - 1) * 8) & 0xff; + buf[i] = (val >> (e == PACK_ENDIAN_LITTLE ? i : size - i - 1) * 8) & 0xff; } enum pack_status pack(void *buf_, size_t size, const char *fmt, ...) { - enum endian endianness = BIG; + enum pack_endian endianness = PACK_ENDIAN_BIG; unsigned char *buf = buf_; size_t offset = 0; va_list ap; @@ -36,19 +36,19 @@ enum pack_status pack(void *buf_, size_t size, const char *fmt, ...) tr_debug("i: %d, fmt[i]: %c", i, fmt[i]); sign = islower(fmt[i]); switch (fmt[i]) { - case '>': endianness = BIG; continue; - case '<': endianness = LITTLE; continue; - case 'b': val.s = va_arg(ap, int ); break; - case 'B': val.u = va_arg(ap, unsigned ); break; - case 'h': val.s = va_arg(ap, int ); break; - case 'H': val.u = va_arg(ap, unsigned ); break; - case 'i': val.s = va_arg(ap, int ); break; - case 'I': val.u = va_arg(ap, unsigned ); break; - case 'l': val.s = va_arg(ap, long ); break; - case 'L': val.u = va_arg(ap, unsigned long ); break; - case 'q': val.s = va_arg(ap, long long); break; - case 'Q': val.u = va_arg(ap, unsigned long long); break; - case 'x': val.u = 0; sign = false; break; + case '>': endianness = PACK_ENDIAN_BIG; continue; + case '<': endianness = PACK_ENDIAN_LITTLE; continue; + case PACK_TYPE_SCHAR: val.s = va_arg(ap, int); break; + case PACK_TYPE_UCHAR: val.u = va_arg(ap, unsigned); break; + case PACK_TYPE_SHORT: val.s = va_arg(ap, int); break; + case PACK_TYPE_USHORT: val.u = va_arg(ap, unsigned); break; + case PACK_TYPE_INT: val.s = va_arg(ap, int); break; + case PACK_TYPE_UINT: val.u = va_arg(ap, unsigned); break; + case PACK_TYPE_LONG: val.s = va_arg(ap, long); break; + case PACK_TYPE_ULONG: val.u = va_arg(ap, unsigned long); break; + case PACK_TYPE_LLONG: val.s = va_arg(ap, long long); break; + case PACK_TYPE_ULLONG: val.u = va_arg(ap, unsigned long long); break; + case PACK_TYPE_PADDING: val.u = 0; sign = false; break; default: return PACK_FMTINVAL; } tr_debug("i: %d, fmt[i]: %c, sign: %ssigned", i, fmt[i], sign ? "" : "un"); @@ -20,6 +20,27 @@ extern enum pack_trace { PACK_TRACE_ALL, } pack_trace; +enum pack_type { + PACK_TYPE_SCHAR = 'b', + PACK_TYPE_UCHAR = 'B', + PACK_TYPE_SHORT = 'h', + PACK_TYPE_USHORT = 'H', + PACK_TYPE_INT = 'i', + PACK_TYPE_UINT = 'I', + PACK_TYPE_LONG = 'l', + PACK_TYPE_ULONG = 'L', + PACK_TYPE_LLONG = 'q', + PACK_TYPE_ULLONG = 'Q', + PACK_TYPE_FLOAT = 'f', + PACK_TYPE_DOUBLE = 'd', + PACK_TYPE_PADDING = 'x', +}; + +enum pack_endian { + PACK_ENDIAN_BIG, + PACK_ENDIAN_LITTLE +}; + enum pack_status pack(void *dest, size_t size, const char *fmt, ...); enum pack_status unpack(const void *buf, size_t size, const char *fmt, ...); @@ -15,12 +15,12 @@ #include "pack.h" #include "trace.h" -static uintmax_t read_val(const unsigned char *buf, size_t size, enum endian e) +static uintmax_t read_val(const unsigned char *buf, size_t size, enum pack_endian e) { uintmax_t val = 0; for (size_t i = 0; i < size; i++) { - val |= (uintmax_t)(buf[i] & 0xff) << (e == LITTLE ? i : size - i - 1) * 8; + val |= (uintmax_t)(buf[i] & 0xff) << (e == PACK_ENDIAN_LITTLE ? i : size - i - 1) * 8; } return val; @@ -38,7 +38,7 @@ static intmax_t minval(size_t s) enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...) { - enum endian endianness = BIG; + enum pack_endian endianness = PACK_ENDIAN_BIG; const unsigned char *buf = buf_; size_t offset = 0; va_list ap; @@ -84,21 +84,21 @@ enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...) tr_debug("count: %" PRIuSIZE ", i: %d, fmt[i]: %c, sign: %ssigned", count, i, fmt[i], sign ? "" : "un"); switch (fmt[i]) { - case '>': endianness = BIG; continue; - case '<': endianness = LITTLE; continue; - case 'b': arg.b = va_arg(ap, signed char *); break; - case 'B': arg.B = va_arg(ap, unsigned char *); break; - case 'h': arg.h = va_arg(ap, short *); break; - case 'H': arg.H = va_arg(ap, unsigned short *); break; - case 'i': arg.i = va_arg(ap, int *); break; - case 'I': arg.I = va_arg(ap, unsigned *); break; - case 'l': arg.l = va_arg(ap, long *); break; - case 'L': arg.L = va_arg(ap, unsigned long *); break; - 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; + case '>': endianness = PACK_ENDIAN_BIG; continue; + case '<': endianness = PACK_ENDIAN_LITTLE; continue; + case PACK_TYPE_UCHAR: arg.b = va_arg(ap, signed char *); break; + case PACK_TYPE_SCHAR: arg.B = va_arg(ap, unsigned char *); break; + case PACK_TYPE_SHORT: arg.h = va_arg(ap, short *); break; + case PACK_TYPE_USHORT: arg.H = va_arg(ap, unsigned short *); break; + case PACK_TYPE_INT: arg.i = va_arg(ap, int *); break; + case PACK_TYPE_UINT: arg.I = va_arg(ap, unsigned *); break; + case PACK_TYPE_LONG: arg.l = va_arg(ap, long *); break; + case PACK_TYPE_ULONG: arg.L = va_arg(ap, unsigned long *); break; + case PACK_TYPE_LLONG: arg.q = va_arg(ap, long long *); break; + case PACK_TYPE_ULLONG: arg.Q = va_arg(ap, unsigned long long *); break; + case PACK_TYPE_FLOAT: arg.f = va_arg(ap, float *); break; + case PACK_TYPE_DOUBLE: arg.d = va_arg(ap, double *); break; + case PACK_TYPE_PADDING: break; default: return PACK_FMTINVAL; } |