aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.c20
-rw-r--r--common.h6
-rw-r--r--pack.c32
-rw-r--r--pack.h21
-rw-r--r--unpack.c36
5 files changed, 68 insertions, 47 deletions
diff --git a/common.c b/common.c
index 61cab15..6f74b1d 100644
--- a/common.c
+++ b/common.c
@@ -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;
}
diff --git a/common.h b/common.h
index e4eebb0..183392a 100644
--- a/common.h
+++ b/common.h
@@ -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
diff --git a/pack.c b/pack.c
index 3f25ab8..9d7046c 100644
--- a/pack.c
+++ b/pack.c
@@ -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");
diff --git a/pack.h b/pack.h
index 1cc0851..daf0699 100644
--- a/pack.h
+++ b/pack.h
@@ -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, ...);
diff --git a/unpack.c b/unpack.c
index 7d2b08a..467b6bf 100644
--- a/unpack.c
+++ b/unpack.c
@@ -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;
}