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".
This commit is contained in:
@@ -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
|
* @addr: pointer of @length bytes. If @length is zero, this may
|
||||||
* also be %NULL.
|
* also be %NULL.
|
||||||
* @length: number of bytes in @addr. May also be zero, in which
|
* @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
|
* @delimiter: either '\0', otherwise the output string will have the
|
||||||
* given delimiter character between each two hex numbers.
|
* given delimiter character between each two hex numbers.
|
||||||
* @upper_case: if TRUE, use upper case ASCII characters for hex.
|
* @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
|
* @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
|
* a @delimiter is specified. In that case, the allocated buffer will
|
||||||
* be returned and must be freed by the caller.
|
* be returned and must be freed by the caller.
|
||||||
* If not %NULL, the buffer must already be preallocated and contain
|
* 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
|
* 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.
|
* 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.
|
* an empty string is returned.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
nm_utils_bin2hexstr_full(gconstpointer addr,
|
nm_utils_bin2hexstr_fuller(gconstpointer addr,
|
||||||
gsize length,
|
gsize length,
|
||||||
char delimiter,
|
char delimiter,
|
||||||
gboolean upper_case,
|
gboolean upper_case,
|
||||||
|
gboolean with_leading_zero,
|
||||||
char *out)
|
char *out)
|
||||||
{
|
{
|
||||||
const guint8 *in = addr;
|
const guint8 *in = addr;
|
||||||
const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef";
|
const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||||
char *out0;
|
char *out0;
|
||||||
|
|
||||||
if (out)
|
nm_assert(with_leading_zero || delimiter != '\0');
|
||||||
out0 = out;
|
|
||||||
else {
|
|
||||||
out0 = out =
|
|
||||||
g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @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. */
|
* 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) {
|
if (length > 0) {
|
||||||
nm_assert(in);
|
nm_assert(in);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const guint8 v = *in++;
|
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];
|
*out++ = LOOKUP[v & 0x0F];
|
||||||
length--;
|
length--;
|
||||||
if (!length)
|
if (length == 0)
|
||||||
break;
|
break;
|
||||||
if (delimiter)
|
if (delimiter != '\0')
|
||||||
*out++ = delimiter;
|
*out++ = delimiter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2619,12 +2619,23 @@ nm_ascii_is_regular(char ch)
|
|||||||
return ch >= ' ' && ch < 127;
|
return ch >= ' ' && ch < 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *nm_utils_bin2hexstr_full(gconstpointer addr,
|
char *nm_utils_bin2hexstr_fuller(gconstpointer addr,
|
||||||
gsize length,
|
gsize length,
|
||||||
char delimiter,
|
char delimiter,
|
||||||
gboolean upper_case,
|
gboolean upper_case,
|
||||||
|
gboolean with_leading_zero,
|
||||||
char *out);
|
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);
|
char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len);
|
||||||
|
|
||||||
#define nm_utils_bin2hexstr_a(addr, length, delimiter, upper_case, str_to_free) \
|
#define nm_utils_bin2hexstr_a(addr, length, delimiter, upper_case, str_to_free) \
|
||||||
|
Reference in New Issue
Block a user