diff options
author | Tomasz Kramkowski <tk@the-tk.com> | 2020-09-10 18:41:04 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tk@the-tk.com> | 2020-09-10 18:41:04 +0100 |
commit | 96c4296ae8c1a5b3bdfa826d5b6ef8f52e046e5e (patch) | |
tree | f1d7d920634bb4202db435c0edecf4325dd4bb44 | |
parent | bfed857f76ad177cc17db499339ea0ede7947d1e (diff) | |
download | pack-96c4296ae8c1a5b3bdfa826d5b6ef8f52e046e5e.tar.gz pack-96c4296ae8c1a5b3bdfa826d5b6ef8f52e046e5e.tar.xz pack-96c4296ae8c1a5b3bdfa826d5b6ef8f52e046e5e.zip |
Allow for a conversion count
-rw-r--r-- | unpack.c | 55 |
1 files changed, 29 insertions, 26 deletions
@@ -39,6 +39,7 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...) for (int i = 0; fmt[i] != '\0'; i++) { bool sign = islower(fmt[i]); + unsigned long long count = 1; size_t s; union { signed char *b; @@ -75,39 +76,41 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...) tr_debug("s: %zu", s); if (s == (size_t)-1) return PACK_FMTINVAL; - if (size - offset < s) return PACK_TOOSMALL; + if (size - offset < s * count) return PACK_TOOSMALL; if (fmt[i] == 'x') goto skip; - val.u = read_val(buf, s, endianness); - tr_debug("val.u: %" PRIuMAX, val.u); - - if (sign) { - intmax_t vals; - if (!(val.u & (UINTMAX_C(1) << (s * 8 - 1)))) { - vals = val.u; - } else { - uintmax_t offt = UINTMAX_MAX >> (sizeof offt * CHAR_BIT - s * 8); - vals = val.u - offt - 1; + for (unsigned long long j = 0; j < count; j++) { + val.u = read_val(buf + s * j, s, endianness); + tr_debug("val.u: %" PRIuMAX, val.u); + + if (sign) { + intmax_t vals; + if (!(val.u & (UINTMAX_C(1) << (s * 8 - 1)))) { + vals = val.u; + } else { + uintmax_t offt = UINTMAX_MAX >> (sizeof offt * CHAR_BIT - s * 8); + vals = val.u - offt - 1; + } + val.s = vals; + tr_debug("val.s: %" PRIdMAX, val.s); } - val.s = vals; - tr_debug("val.s: %" PRIdMAX, val.s); - } - switch (fmt[i]) { - case 'b': *arg.b = val.s; break; - case 'B': *arg.B = val.u; break; - case 'h': *arg.h = val.s; break; - case 'H': *arg.H = val.u; break; - case 'i': *arg.i = val.s; break; - case 'I': *arg.I = val.u; break; - case 'l': *arg.l = val.s; break; - case 'L': *arg.L = val.u; break; - case 'q': *arg.q = val.s; break; - case 'Q': *arg.Q = val.u; break; + switch (fmt[i]) { + case 'b': arg.b[j] = val.s; break; + case 'B': arg.B[j] = val.u; break; + case 'h': arg.h[j] = val.s; break; + case 'H': arg.H[j] = val.u; break; + case 'i': arg.i[j] = val.s; break; + case 'I': arg.I[j] = val.u; break; + case 'l': arg.l[j] = val.s; break; + case 'L': arg.L[j] = val.u; break; + case 'q': arg.q[j] = val.s; break; + case 'Q': arg.Q[j] = val.u; break; + } } skip: - offset += s; + offset += s * count; } va_end(ap); |