summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-07-13 17:18:29 +0200
committerThomas Haller <thaller@redhat.com>2022-07-18 14:58:00 +0200
commit4dd4d5b7591f96fdf1c8a2ae1c9caaffa11d9a33 (patch)
tree48adb2fa65257b04118092404c01191f3da88707
parente122df6005b88efec1d6ee3b114e7356c65373b1 (diff)
downloadNetworkManager-4dd4d5b7591f96fdf1c8a2ae1c9caaffa11d9a33.tar.gz
glib-aux: don't use GPtrArray in nm_utils_strsplit_quoted()
GPtrArray requires an additional heap allocation for the GPtrArray. Utterly useless in the majority of cases. Anyway. Allocating (and exponentially grown) a buffer is not too hard, just slightly more cumbersome. Since nm_utils_strsplit_quoted() is heavily unit tested and entirely self-contained, let's opt for the more complicated implementation and avoid the extra allocation.
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c
index 67a4d58852..6128b0cb8a 100644
--- a/src/libnm-glib-aux/nm-shared-utils.c
+++ b/src/libnm-glib-aux/nm-shared-utils.c
@@ -2288,9 +2288,11 @@ nm_utils_escaped_tokens_options_split(char *str, const char **out_key, const cha
char **
nm_utils_strsplit_quoted(const char *str)
{
- gs_unref_ptrarray GPtrArray *arr = NULL;
- gs_free char *str_out = NULL;
- CharLookupTable ch_lookup;
+ char **arr = NULL;
+ gsize arr_len = 0;
+ gsize arr_alloc = 0;
+ gs_free char *str_out = NULL;
+ CharLookupTable ch_lookup;
nm_assert(str);
@@ -2347,19 +2349,32 @@ nm_utils_strsplit_quoted(const char *str)
str++;
}
- if (!arr)
- arr = g_ptr_array_new();
- g_ptr_array_add(arr, g_strndup(str_out, j));
+ if (arr_len >= arr_alloc) {
+ if (arr_alloc == 0)
+ arr_alloc = 4;
+ else
+ arr_alloc *= 2;
+ arr = g_realloc(arr, sizeof(char *) * arr_alloc);
+ }
+
+ arr[arr_len++] = g_strndup(str_out, j);
}
if (!arr)
return g_new0(char *, 1);
- g_ptr_array_add(arr, NULL);
-
/* We want to return an optimally sized strv array, with no excess
* memory allocated. Hence, clone once more. */
- return nm_memdup(arr->pdata, sizeof(char *) * arr->len);
+
+ if (arr_len + 1u != arr_alloc) {
+ gs_free char **arr_old = arr;
+
+ arr = g_new(char *, arr_len + 1u);
+ memcpy(arr, arr_old, sizeof(char *) * arr_len);
+ }
+
+ arr[arr_len] = NULL;
+ return arr;
}
/*****************************************************************************/