summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
Diffstat (limited to 'misc')
-rw-r--r--misc/bstr.c37
-rw-r--r--misc/bstr.h4
2 files changed, 41 insertions, 0 deletions
diff --git a/misc/bstr.c b/misc/bstr.c
index 8c47b447d4..09eb6af25b 100644
--- a/misc/bstr.c
+++ b/misc/bstr.c
@@ -454,3 +454,40 @@ struct bstr bstr_get_ext(struct bstr s)
return (struct bstr){NULL, 0};
return bstr_splice(s, dotpos + 1, s.len);
}
+
+static int h_to_i(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+
+ return -1; // invalid char
+}
+
+bool bstr_decode_hex(void *talloc_ctx, struct bstr hex, struct bstr *out)
+{
+ if (!out)
+ return false;
+
+ char *arr = talloc_array(talloc_ctx, char, hex.len / 2);
+ int len = 0;
+
+ while (hex.len >= 2) {
+ int a = h_to_i(hex.start[0]);
+ int b = h_to_i(hex.start[1]);
+ hex = bstr_splice(hex, 2, hex.len);
+
+ if (a < 0 || b < 0) {
+ talloc_free(arr);
+ return false;
+ }
+
+ arr[len++] = (a << 4) | b;
+ }
+
+ *out = (struct bstr){ .start = arr, .len = len };
+ return true;
+}
diff --git a/misc/bstr.h b/misc/bstr.h
index 63865a4421..199f300ba1 100644
--- a/misc/bstr.h
+++ b/misc/bstr.h
@@ -80,6 +80,10 @@ double bstrtod(struct bstr str, struct bstr *rest);
void bstr_lower(struct bstr str);
int bstr_sscanf(struct bstr str, const char *format, ...);
+// Decode a string containing hexadecimal data. All whitespace will be silently
+// ignored. When successful, this allocates a new array to store the output.
+bool bstr_decode_hex(void *talloc_ctx, struct bstr hex, struct bstr *out);
+
// Decode the UTF-8 code point at the start of the string, and return the
// character.
// After calling this function, *out_next will point to the next character.