diff options
author | Thomas Haller <thaller@redhat.com> | 2022-12-14 10:37:10 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-12-19 11:29:16 +0100 |
commit | b23c505fca64718bcb28d76d5884110ae64461cb (patch) | |
tree | b91343e21eb72a8c0d5a16e22a9626b996ddf670 | |
parent | df0408f0f6a9c38e8c9a4aed43efa02cb23de9b6 (diff) | |
download | NetworkManager-b23c505fca64718bcb28d76d5884110ae64461cb.tar.gz |
glib-aux: add "with_leading_zero" to nm_utils_bin2hexstr_full()
dhclient writes binary data as colon-separated hex strings
like nm_utils_bin2hexstr_full() does. But it only writes single
digits for values smaller than 0x10. Add an option to support
that mode.
However, there are many callers of nm_utils_bin2hexstr_full() already,
and they all don't care about the new option. Maybe this should this
not be a boolean argument, instead the function should accept a
flags argument. That is not done for now. Just add another "fuller"
variant. It's still easy to understand, because the "full" variant
is just a more limited functionality of "fuller".
-rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.c | 47 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.h | 21 |
2 files changed, 45 insertions, 23 deletions
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index c703495e71..d2e989841f 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -4368,7 +4368,7 @@ nm_utils_memeqzero(gconstpointer data, gsize length) } /** - * nm_utils_bin2hexstr_full: + * nm_utils_bin2hexstr_fuller: * @addr: pointer of @length bytes. If @length is zero, this may * also be %NULL. * @length: number of bytes in @addr. May also be zero, in which @@ -4376,12 +4376,17 @@ nm_utils_memeqzero(gconstpointer data, gsize length) * @delimiter: either '\0', otherwise the output string will have the * given delimiter character between each two hex numbers. * @upper_case: if TRUE, use upper case ASCII characters for hex. + * @with_leading_zero: if TRUE, then the hex values from 0 to 0xf + * are written as "00" to "0f", respectively. Otherwise, the leading + * zero is dropped. With @with_leading_zero set to FALSE, the resulting + * string may be shorter than expected. @delimiter must be set + * if @with_leading_zero is FALSE. * @out: if %NULL, the function will allocate a new buffer of - * either (@length*2+1) or (@length*3) bytes, depending on whether + * either (@length*2+1) or MAX(1, (@length*3)) bytes, depending on whether * a @delimiter is specified. In that case, the allocated buffer will * be returned and must be freed by the caller. * If not %NULL, the buffer must already be preallocated and contain - * at least (@length*2+1) or (@length*3) bytes, depending on the delimiter. + * at least (@length*2+1) or MAX(1, (@length*3)) bytes, depending on the delimiter. * If @length is zero, then of course at least one byte will be allocated * or @out (if given) must contain at least room for the trailing NUL byte. * @@ -4391,37 +4396,43 @@ nm_utils_memeqzero(gconstpointer data, gsize length) * an empty string is returned. */ char * -nm_utils_bin2hexstr_full(gconstpointer addr, - gsize length, - char delimiter, - gboolean upper_case, - char *out) +nm_utils_bin2hexstr_fuller(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + gboolean with_leading_zero, + char *out) { const guint8 *in = addr; const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; char *out0; - if (out) - out0 = out; - else { - out0 = out = - g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u)); - } + nm_assert(with_leading_zero || delimiter != '\0'); - /* @out must contain at least @length*3 bytes if @delimiter is set, + /* @out must contain at least (MAX(1, @length*3)) bytes if @delimiter is set, * otherwise, @length*2+1. */ + if (!out) + out = g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u)); + + out0 = out; + if (length > 0) { nm_assert(in); for (;;) { const guint8 v = *in++; + guint8 v_hi; - *out++ = LOOKUP[v >> 4]; + v_hi = (v >> 4); + if (v_hi != 0 || with_leading_zero) { + nm_assert(v_hi < 16); + *out++ = LOOKUP[v_hi]; + } *out++ = LOOKUP[v & 0x0F]; length--; - if (!length) + if (length == 0) break; - if (delimiter) + if (delimiter != '\0') *out++ = delimiter; } } diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index b65d9e93d0..044f34abf0 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -2619,11 +2619,22 @@ nm_ascii_is_regular(char ch) return ch >= ' ' && ch < 127; } -char *nm_utils_bin2hexstr_full(gconstpointer addr, - gsize length, - char delimiter, - gboolean upper_case, - char *out); +char *nm_utils_bin2hexstr_fuller(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + gboolean with_leading_zero, + char *out); + +static inline char * +nm_utils_bin2hexstr_full(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + char *out) +{ + return nm_utils_bin2hexstr_fuller(addr, length, delimiter, upper_case, TRUE, out); +} char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len); |