aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2023-01-23 12:08:09 -0600
committerDenis Kenzior <denkenz@gmail.com>2023-01-23 12:08:09 -0600
commit7b3ac120e9d76e0b8318c3e6b5393777f198b404 (patch)
tree0ee1bfaba2c902dfb42f3d608e1f5a2fe0fc36d2
parentf1c916d71411deb335c93c380a56bb225bbd92af (diff)
ell: Add l_util_hexstringv and l_util_hexstringv_upper
-rw-r--r--ell/ell.sym2
-rw-r--r--ell/util.c60
-rw-r--r--ell/util.h2
3 files changed, 64 insertions, 0 deletions
diff --git a/ell/ell.sym b/ell/ell.sym
index 4d8596e0..7b5caa16 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -15,6 +15,8 @@ global:
l_streq0;
l_util_hexstring;
l_util_hexstring_upper;
+ l_util_hexstringv;
+ l_util_hexstringv_upper;
l_util_from_hexstring;
l_util_hexdump;
l_util_hexdump_two;
diff --git a/ell/util.c b/ell/util.c
index 9c9c4765..2829a330 100644
--- a/ell/util.c
+++ b/ell/util.c
@@ -376,6 +376,36 @@ static char *hexstring_common(const unsigned char *buf, size_t len,
return str;
}
+static char *hexstringv_common(const struct iovec *iov, size_t n_iov,
+ const char hexdigits[static 16])
+{
+ char *str;
+ size_t i, j, c;
+ size_t len;
+
+ if (unlikely(!iov || !n_iov))
+ return NULL;
+
+ for (i = 0, len = 0; i < n_iov; i++)
+ len += iov[i].iov_len;
+
+ str = l_malloc(len * 2 + 1);
+ c = 0;
+
+ for (i = 0; i < n_iov; i++) {
+ const uint8_t *buf = iov[i].iov_base;
+
+ for (j = 0; j < iov[i].iov_len; j++) {
+ str[c++] = hexdigits[buf[j] >> 4];
+ str[c++] = hexdigits[buf[j] & 0xf];
+ }
+ }
+
+ str[len * 2] = '\0';
+
+ return str;
+}
+
/**
* l_util_hexstring:
* @buf: buffer pointer
@@ -407,6 +437,36 @@ LIB_EXPORT char *l_util_hexstring_upper(const void *buf, size_t len)
}
/**
+ * l_util_hexstringv:
+ * @iov: iovec
+ * @n_iov: length of the iovec
+ *
+ * Returns: a newly allocated hex string. Note that the string will contain
+ * lower case hex digits a-f. If you require upper case hex digits, use
+ * @l_util_hexstringv_upper
+ **/
+LIB_EXPORT char *l_util_hexstringv(const struct iovec *iov, size_t n_iov)
+{
+ static const char hexdigits[] = "0123456789abcdef";
+ return hexstringv_common(iov, n_iov, hexdigits);
+}
+
+/**
+ * l_util_hexstringv_upper:
+ * @iov: iovec
+ * @n_iov: length of the iovec
+ *
+ * Returns: a newly allocated hex string. Note that the string will contain
+ * upper case hex digits a-f. If you require lower case hex digits, use
+ * @l_util_hexstringv
+ **/
+LIB_EXPORT char *l_util_hexstringv_upper(const struct iovec *iov, size_t n_iov)
+{
+ static const char hexdigits[] = "0123456789ABCDEF";
+ return hexstringv_common(iov, n_iov, hexdigits);
+}
+
+/**
* l_util_from_hexstring:
* @str: Null-terminated string containing the hex-encoded bytes
* @out_len: Number of bytes decoded
diff --git a/ell/util.h b/ell/util.h
index fb6d78f1..19987203 100644
--- a/ell/util.h
+++ b/ell/util.h
@@ -282,6 +282,8 @@ bool l_streq0(const char *a, const char *b);
char *l_util_hexstring(const void *buf, size_t len);
char *l_util_hexstring_upper(const void *buf, size_t len);
+char *l_util_hexstringv(const struct iovec *iov, size_t n_iov);
+char *l_util_hexstringv_upper(const struct iovec *iov, size_t n_iov);
unsigned char *l_util_from_hexstring(const char *str, size_t *out_len);
typedef void (*l_util_hexdump_func_t) (const char *str, void *user_data);