summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2019-01-14 23:32:53 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2019-01-28 23:58:53 +0000
commit0423b61aa8dd75b3141e13cf9276b8fa14ceb473 (patch)
tree8437f60dc6f6f817f96f3118db61bf91383cbd7a
parentd01ef75ab876d79c9a0a73cdefb4ccfc60bb47f8 (diff)
add osmo_hexdump_buf() and test
Add osmo_hexdump_buf() as an all-purpose hexdump function, which all other osmo_hexdump_*() implementations now call. It absorbs the static _osmo_hexdump(). Add tests for osmo_hexdump_buf(). Rationale: recently during patch review, a situation came up where two hexdumps in a single printf would have been useful. Now I've faced a similar situation again, in ongoing development. So I decided it is time to provide this API. The traditional osmo_hexdump() API returns a non-const char*, which should probably have been a const instead. Particularly this new function may return a string constant "" if the buf is NULL or empty, so return const char*. That is why the older implementations calling osmo_hexdump_buf() separately return the buffer instead of the const return value directly. Change-Id: I590595567b218b24e53c9eb1fd8736c0324d371d
-rw-r--r--include/osmocom/core/utils.h3
-rw-r--r--src/utils.c49
-rw-r--r--tests/utils/utils_test.c25
-rw-r--r--tests/utils/utils_test.ok97
4 files changed, 163 insertions, 11 deletions
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 987080e2..fe360b33 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -56,6 +56,9 @@ int osmo_hexparse(const char *str, uint8_t *b, int max_len);
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
char *osmo_hexdump(const unsigned char *buf, int len);
char *osmo_hexdump_nospc(const unsigned char *buf, int len);
+const char *osmo_hexdump_buf(char *out_buf, size_t out_buf_size, const unsigned char *buf, int len, const char *delim,
+ bool delim_after_last);
+
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len) __attribute__((__deprecated__));
#define osmo_static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1] __attribute__((__unused__));
diff --git a/src/utils.c b/src/utils.c
index d1da4fa8..0b2ed31d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -219,30 +219,55 @@ int osmo_hexparse(const char *str, uint8_t *b, int max_len)
static char hexd_buff[4096];
static const char hex_chars[] = "0123456789abcdef";
-static char *_osmo_hexdump(const unsigned char *buf, int len, char *delim)
+/*! Convert binary sequence to hexadecimal ASCII string.
+ * \param[out] out_buf Output buffer to write the resulting string to.
+ * \param[in] out_buf_size sizeof(out_buf).
+ * \param[in] buf Input buffer, pointer to sequence of bytes.
+ * \param[in] len Length of input buf in number of bytes.
+ * \param[in] delim String to separate each byte; NULL or "" for no delim.
+ * \param[in] delim_after_last If true, end the string in delim (true: "1a:ef:d9:", false: "1a:ef:d9");
+ * if out_buf has insufficient space, the string will always end in a delim.
+ * \returns out_buf, containing a zero-terminated string, or "" (empty string) if out_buf == NULL or out_buf_size < 1.
+ *
+ * This function will print a sequence of bytes as hexadecimal numbers, adding one delim between each byte (e.g. for
+ * delim passed as ":", return a string like "1a:ef:d9").
+ *
+ * The delim_after_last argument exists to be able to exactly show the original osmo_hexdump() behavior, which always
+ * ends the string with a delimiter.
+ */
+const char *osmo_hexdump_buf(char *out_buf, size_t out_buf_size, const unsigned char *buf, int len, const char *delim,
+ bool delim_after_last)
{
int i;
- char *cur = hexd_buff;
+ char *cur = out_buf;
+ size_t delim_len;
+
+ if (!out_buf || !out_buf_size)
+ return "";
+
+ delim = delim ? : "";
+ delim_len = strlen(delim);
- hexd_buff[0] = 0;
for (i = 0; i < len; i++) {
const char *delimp = delim;
- int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
- if (len_remain < 3)
+ int len_remain = out_buf_size - (cur - out_buf) - 1;
+ if (len_remain < (2 + delim_len)
+ && !(!delim_after_last && i == (len - 1) && len_remain >= 2))
break;
*cur++ = hex_chars[buf[i] >> 4];
*cur++ = hex_chars[buf[i] & 0xf];
+ if (i == (len - 1) && !delim_after_last)
+ break;
+
while (len_remain > 1 && *delimp) {
*cur++ = *delimp++;
len_remain--;
}
-
- *cur = 0;
}
- hexd_buff[sizeof(hexd_buff)-1] = 0;
- return hexd_buff;
+ *cur = '\0';
+ return out_buf;
}
/*! Convert a sequence of unpacked bits to ASCII string
@@ -292,7 +317,8 @@ char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
*/
char *osmo_hexdump(const unsigned char *buf, int len)
{
- return _osmo_hexdump(buf, len, " ");
+ osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, " ", true);
+ return hexd_buff;
}
/*! Convert binary sequence to hexadecimal ASCII string
@@ -308,7 +334,8 @@ char *osmo_hexdump(const unsigned char *buf, int len)
*/
char *osmo_hexdump_nospc(const unsigned char *buf, int len)
{
- return _osmo_hexdump(buf, len, "");
+ osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, "", true);
+ return hexd_buff;
}
/* Compat with previous typo to preserve abi */
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index a773b3f5..822861fb 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -37,6 +37,7 @@
static void hexdump_test(void)
{
uint8_t data[4098];
+ char buf[256];
int i;
for (i = 0; i < ARRAY_SIZE(data); ++i)
@@ -44,10 +45,34 @@ static void hexdump_test(void)
printf("Plain dump\n");
printf("%s\n", osmo_hexdump(data, 4));
+ printf("%s\n", osmo_hexdump_nospc(data, 4));
printf("Corner case\n");
printf("%s\n", osmo_hexdump(data, ARRAY_SIZE(data)));
printf("%s\n", osmo_hexdump_nospc(data, ARRAY_SIZE(data)));
+
+#define _HEXDUMP_BUF_TEST(SIZE, DELIM, DELIM_AFTER) \
+ buf[0] = '!'; \
+ buf[1] = '\0'; \
+ printf("osmo_hexdump_buf(buf, " #SIZE ", data, 4, %s, " #DELIM_AFTER ")\n = \"%s\"\n", \
+ DELIM ? #DELIM : "NULL", \
+ osmo_hexdump_buf(buf, SIZE, data, 4, DELIM, DELIM_AFTER))
+#define HEXDUMP_BUF_TEST(DELIM) \
+ _HEXDUMP_BUF_TEST(sizeof(buf), DELIM, false); \
+ _HEXDUMP_BUF_TEST(sizeof(buf), DELIM, true); \
+ _HEXDUMP_BUF_TEST(6, DELIM, false); \
+ _HEXDUMP_BUF_TEST(7, DELIM, false); \
+ _HEXDUMP_BUF_TEST(8, DELIM, false); \
+ _HEXDUMP_BUF_TEST(6, DELIM, true); \
+ _HEXDUMP_BUF_TEST(7, DELIM, true); \
+ _HEXDUMP_BUF_TEST(8, DELIM, true)
+
+ HEXDUMP_BUF_TEST("[delim]");
+ HEXDUMP_BUF_TEST(" ");
+ HEXDUMP_BUF_TEST(":");
+ HEXDUMP_BUF_TEST("::");
+ HEXDUMP_BUF_TEST("");
+ HEXDUMP_BUF_TEST(NULL);
}
static void hexparse_test(void)
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index 65e32ed2..8d7ced83 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -1,8 +1,105 @@
Plain dump
00 01 02 03
+00010203
Corner case
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "[delim]", false)
+ = "00[delim]01[delim]02[delim]03"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "[delim]", true)
+ = "00[delim]01[delim]02[delim]03[delim]"
+osmo_hexdump_buf(buf, 6, data, 4, "[delim]", false)
+ = ""
+osmo_hexdump_buf(buf, 7, data, 4, "[delim]", false)
+ = ""
+osmo_hexdump_buf(buf, 8, data, 4, "[delim]", false)
+ = ""
+osmo_hexdump_buf(buf, 6, data, 4, "[delim]", true)
+ = ""
+osmo_hexdump_buf(buf, 7, data, 4, "[delim]", true)
+ = ""
+osmo_hexdump_buf(buf, 8, data, 4, "[delim]", true)
+ = ""
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, " ", false)
+ = "00 01 02 03"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, " ", true)
+ = "00 01 02 03 "
+osmo_hexdump_buf(buf, 6, data, 4, " ", false)
+ = "00 "
+osmo_hexdump_buf(buf, 7, data, 4, " ", false)
+ = "00 01 "
+osmo_hexdump_buf(buf, 8, data, 4, " ", false)
+ = "00 01 "
+osmo_hexdump_buf(buf, 6, data, 4, " ", true)
+ = "00 "
+osmo_hexdump_buf(buf, 7, data, 4, " ", true)
+ = "00 01 "
+osmo_hexdump_buf(buf, 8, data, 4, " ", true)
+ = "00 01 "
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, ":", false)
+ = "00:01:02:03"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, ":", true)
+ = "00:01:02:03:"
+osmo_hexdump_buf(buf, 6, data, 4, ":", false)
+ = "00:"
+osmo_hexdump_buf(buf, 7, data, 4, ":", false)
+ = "00:01:"
+osmo_hexdump_buf(buf, 8, data, 4, ":", false)
+ = "00:01:"
+osmo_hexdump_buf(buf, 6, data, 4, ":", true)
+ = "00:"
+osmo_hexdump_buf(buf, 7, data, 4, ":", true)
+ = "00:01:"
+osmo_hexdump_buf(buf, 8, data, 4, ":", true)
+ = "00:01:"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "::", false)
+ = "00::01::02::03"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "::", true)
+ = "00::01::02::03::"
+osmo_hexdump_buf(buf, 6, data, 4, "::", false)
+ = "00::"
+osmo_hexdump_buf(buf, 7, data, 4, "::", false)
+ = "00::"
+osmo_hexdump_buf(buf, 8, data, 4, "::", false)
+ = "00::"
+osmo_hexdump_buf(buf, 6, data, 4, "::", true)
+ = "00::"
+osmo_hexdump_buf(buf, 7, data, 4, "::", true)
+ = "00::"
+osmo_hexdump_buf(buf, 8, data, 4, "::", true)
+ = "00::"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "", false)
+ = "00010203"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, "", true)
+ = "00010203"
+osmo_hexdump_buf(buf, 6, data, 4, "", false)
+ = "0001"
+osmo_hexdump_buf(buf, 7, data, 4, "", false)
+ = "000102"
+osmo_hexdump_buf(buf, 8, data, 4, "", false)
+ = "000102"
+osmo_hexdump_buf(buf, 6, data, 4, "", true)
+ = "0001"
+osmo_hexdump_buf(buf, 7, data, 4, "", true)
+ = "000102"
+osmo_hexdump_buf(buf, 8, data, 4, "", true)
+ = "000102"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, NULL, false)
+ = "00010203"
+osmo_hexdump_buf(buf, sizeof(buf), data, 4, NULL, true)
+ = "00010203"
+osmo_hexdump_buf(buf, 6, data, 4, NULL, false)
+ = "0001"
+osmo_hexdump_buf(buf, 7, data, 4, NULL, false)
+ = "000102"
+osmo_hexdump_buf(buf, 8, data, 4, NULL, false)
+ = "000102"
+osmo_hexdump_buf(buf, 6, data, 4, NULL, true)
+ = "0001"
+osmo_hexdump_buf(buf, 7, data, 4, NULL, true)
+ = "000102"
+osmo_hexdump_buf(buf, 8, data, 4, NULL, true)
+ = "000102"
Hexparse 0..255 in lower case
rc = 256