diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-08-24 03:04:58 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-08-24 04:19:07 +0200 |
commit | eddc0ffdab239c61cc0e064b6ebd33dfadcef3cd (patch) | |
tree | 831a5b64ed6bbd34d8c3e721665599e7197a4dec /lib | |
parent | e3c0eca95642a846ab65261424a51dd99d954017 (diff) |
Lib: Add functions for reading and writing of bytestrings
Based on patch from Alexander Zubkov, thanks!
Diffstat (limited to 'lib')
-rw-r--r-- | lib/string.h | 3 | ||||
-rw-r--r-- | lib/strtoul.c | 104 |
2 files changed, 86 insertions, 21 deletions
diff --git a/lib/string.h b/lib/string.h index 2829943d..161b7651 100644 --- a/lib/string.h +++ b/lib/string.h @@ -33,6 +33,9 @@ u64 bstrtoul10(const char *str, char **end); u64 bstrtoul16(const char *str, char **end); byte bstrtobyte16(const char *str); +int bstrhextobin(const char *s, byte *b); +int bstrbintohex(const byte *b, size_t len, char *buf, size_t size, char delim); + int patmatch(const byte *pat, const byte *str); static inline char *xbasename(const char *str) diff --git a/lib/strtoul.c b/lib/strtoul.c index a5b11f68..e0c0142f 100644 --- a/lib/strtoul.c +++ b/lib/strtoul.c @@ -25,7 +25,7 @@ bstrtoul10(const char *str, char **end) errno = ERANGE; return UINT64_MAX; } - + out *= 10; out += (**end) - '0'; } @@ -60,29 +60,91 @@ bstrtoul16(const char *str, char **end) return UINT64_MAX; } -byte -bstrtobyte16(const char *str) +static int +fromxdigit(char c) { - byte out = 0; - for (int i=0; i<2; i++) { - switch (str[i]) { - case '0' ... '9': - out *= 16; - out += str[i] - '0'; - break; - case 'a' ... 'f': - out *= 16; - out += str[i] + 10 - 'a'; - break; - case 'A' ... 'F': - out *= 16; - out += str[i] + 10 - 'A'; - break; - default: - errno = ERANGE; + switch (c) + { + case '0' ... '9': + return c - '0'; + case 'a' ... 'f': + return c + 10 - 'a'; + case 'A' ... 'F': + return c + 10 - 'A'; + default: + return -1; + } +} + +int +bstrhextobin(const char *s, byte *b) +{ + int len = 0; + int hi = 0; + + for (; *s; s++) + { + int v = fromxdigit(*s); + if (v < 0) + { + if (strchr(" :-", *s) && !hi) + continue; + else return -1; } + + if (len == INT32_MAX) + return -1; + + if (b) + { + if (!hi) + b[len] = (v << 4); + else + b[len] |= v; + } + + len += hi; + hi = !hi; } - return out; + return !hi ? len : -1; +} + +static char +toxdigit(uint b) +{ + if (b < 10) + return ('0' + b); + else if (b < 16) + return ('a' + b - 10); + else + return 0; +} + +int +bstrbintohex(const byte *b, size_t len, char *buf, size_t size, char delim) +{ + ASSERT(size >= 6); + char *bound = buf + size - 3; + + size_t i; + for (i = 0; i < len; i++) + { + if (buf > bound) + { + strcpy(buf - 4, "..."); + return -1; + } + + uint x = b[i]; + buf[0] = toxdigit(x >> 4); + buf[1] = toxdigit(x & 0xF); + buf[2] = delim; + buf += 3; + } + + buf[i ? -1 : 0] = 0; + + return 0; } |