summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-01-14 14:58:53 +0100
committerThomas Haller <thaller@redhat.com>2019-01-14 16:40:39 +0100
commit694533f52933841016227684b75bf113913335c1 (patch)
tree28cb08cb9fb0beedaf5879c008a7565a78bccce9
parentcf30c9f07fb490b5f1833de52636e215be2dd57c (diff)
downloadNetworkManager-694533f52933841016227684b75bf113913335c1.tar.gz
shared: add nm_utils_strbuf_append_bin() helper
Add a version of nm_utils_strbuf_append_*() that does not care about NUL terminate strings, but accept any binary data. That makes it useful for writing a binary buffer.
-rw-r--r--shared/nm-utils/nm-shared-utils.c35
-rw-r--r--shared/nm-utils/nm-shared-utils.h1
-rw-r--r--src/tests/test-general.c84
3 files changed, 116 insertions, 4 deletions
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 93b476d645..c9ef89e96c 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -59,6 +59,41 @@ nm_utils_strbuf_append_c (char **buf, gsize *len, char c)
}
void
+nm_utils_strbuf_append_bin (char **buf, gsize *len, gconstpointer str, gsize str_len)
+{
+ switch (*len) {
+ case 0:
+ return;
+ case 1:
+ if (str_len == 0) {
+ (*buf)[0] = '\0';
+ return;
+ }
+ (*buf)[0] = '\0';
+ *len = 0;
+ (*buf)++;
+ return;
+ default:
+ if (str_len == 0) {
+ (*buf)[0] = '\0';
+ return;
+ }
+ if (str_len >= *len) {
+ memcpy (*buf, str, *len - 1);
+ (*buf)[*len - 1] = '\0';
+ *buf = &(*buf)[*len];
+ *len = 0;
+ } else {
+ memcpy (*buf, str, str_len);
+ *buf = &(*buf)[str_len];
+ (*buf)[0] = '\0';
+ *len -= str_len;
+ }
+ return;
+ }
+}
+
+void
nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str)
{
gsize src_len;
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 76049804f4..ac8fe51ec9 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -342,6 +342,7 @@ _nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len)
void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _nm_printf (3, 4);
void nm_utils_strbuf_append_c (char **buf, gsize *len, char c);
void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
+void nm_utils_strbuf_append_bin (char **buf, gsize *len, gconstpointer str, gsize str_len);
void nm_utils_strbuf_seek_end (char **buf, gsize *len);
const char *nm_strquote (char *buf, gsize buf_len, const char *str);
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 0166655d66..2db6e60f6c 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -1440,6 +1440,82 @@ test_nm_utils_strbuf_append (void)
char buf[NM_STRLEN (BUF_ORIG) + 1];
char str[NM_STRLEN (BUF_ORIG) + 1];
+#define _strbuf_append(buf, len, format, ...) \
+ G_STMT_START { \
+ char **_buf = (buf); \
+ gsize *_len = (len); \
+ const char *_str_iter; \
+ gs_free char *_str = NULL; \
+ \
+ switch (nmtst_get_rand_int () % 4) { \
+ case 0: \
+ nm_utils_strbuf_append (_buf, _len, (format), __VA_ARGS__); \
+ break; \
+ case 1: \
+ _str = g_strdup_printf ((format), __VA_ARGS__); \
+ nm_utils_strbuf_append_str (_buf, _len, _str); \
+ break; \
+ case 2: \
+ _str = g_strdup_printf ((format), __VA_ARGS__); \
+ nm_utils_strbuf_append_bin (_buf, _len, _str, strlen (_str)); \
+ break; \
+ case 3: \
+ _str = g_strdup_printf ((format), __VA_ARGS__); \
+ if (!_str[0]) \
+ nm_utils_strbuf_append_str (_buf, _len, _str); \
+ for (_str_iter = _str; _str_iter[0]; _str_iter++) \
+ nm_utils_strbuf_append_c (_buf, _len, _str_iter[0]); \
+ break; \
+ } \
+ } G_STMT_END
+
+#define _strbuf_append_str(buf, len, str) \
+ G_STMT_START { \
+ char **_buf = (buf); \
+ gsize *_len = (len); \
+ const char *_str = (str); \
+ \
+ switch (nmtst_get_rand_int () % 4) { \
+ case 0: \
+ nm_utils_strbuf_append (_buf, _len, "%s", _str ?: ""); \
+ break; \
+ case 1: \
+ nm_utils_strbuf_append_str (_buf, _len, _str); \
+ break; \
+ case 2: \
+ nm_utils_strbuf_append_bin (_buf, _len, _str, _str ? strlen (_str) : 0); \
+ break; \
+ case 3: \
+ if (!_str || !_str[0]) \
+ nm_utils_strbuf_append_str (_buf, _len, _str); \
+ for (; _str && _str[0]; _str++) \
+ nm_utils_strbuf_append_c (_buf, _len, _str[0]); \
+ break; \
+ } \
+ } G_STMT_END
+
+#define _strbuf_append_c(buf, len, ch) \
+ G_STMT_START { \
+ char **_buf = (buf); \
+ gsize *_len = (len); \
+ char _ch = (ch); \
+ \
+ switch (nmtst_get_rand_int () % 4) { \
+ case 0: \
+ nm_utils_strbuf_append (_buf, _len, "%c", _ch); \
+ break; \
+ case 1: \
+ nm_utils_strbuf_append_str (_buf, _len, ((char[2]) { _ch, 0 })); \
+ break; \
+ case 2: \
+ nm_utils_strbuf_append_bin (_buf, _len, &_ch, 1); \
+ break; \
+ case 3: \
+ nm_utils_strbuf_append_c (_buf, _len, _ch); \
+ break; \
+ } \
+ } G_STMT_END
+
for (buf_len = 0; buf_len < 10; buf_len++) {
for (rep = 0; rep < 50; rep++) {
const int s_len = nmtst_get_rand_int () % (sizeof (str) - 5);
@@ -1463,21 +1539,21 @@ test_nm_utils_strbuf_append (void)
switch (test_mode) {
case 0:
if (s_len == 1) {
- nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]);
+ _strbuf_append_c (&t_buf, &t_len, str[0]);
break;
}
/* fall through */
case 1:
- nm_utils_strbuf_append_str (&t_buf, &t_len, str);
+ _strbuf_append_str (&t_buf, &t_len, str);
break;
case 2:
if (s_len == 1) {
- nm_utils_strbuf_append (&t_buf, &t_len, "%c", str[0]);
+ _strbuf_append (&t_buf, &t_len, "%c", str[0]);
break;
}
/* fall through */
case 3:
- nm_utils_strbuf_append (&t_buf, &t_len, "%s", str);
+ _strbuf_append (&t_buf, &t_len, "%s", str);
break;
case 4:
g_snprintf (t_buf, t_len, "%s", str);