From bc4ba05d3406152d5eb26004645ba6a9942d2924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 15 Oct 2023 15:30:52 +0200 Subject: [PATCH] gstrvbuilder: Add g_strv_builder_take g_strv_builder_take() allows to transfer ownership of the passed in string. This can be useful to avoid additional allocations when using functions that transfer ownership to the caller like g_strdup_printf(). The testcase uses g_strv_builder_take and g_strv_builder_add to demo that calls can be mixed. --- docs/reference/glib/glib-sections.txt.in | 1 + glib/gstrvbuilder.c | 18 ++++++++++++++++++ glib/gstrvbuilder.h | 4 ++++ glib/tests/strvbuilder.c | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/docs/reference/glib/glib-sections.txt.in b/docs/reference/glib/glib-sections.txt.in index a3fe735ae..db8f47230 100644 --- a/docs/reference/glib/glib-sections.txt.in +++ b/docs/reference/glib/glib-sections.txt.in @@ -1604,6 +1604,7 @@ g_strv_builder_unref g_strv_builder_add g_strv_builder_addv g_strv_builder_add_many +g_strv_builder_take g_strv_builder_end diff --git a/glib/gstrvbuilder.c b/glib/gstrvbuilder.c index 91e33987b..12d6a29d5 100644 --- a/glib/gstrvbuilder.c +++ b/glib/gstrvbuilder.c @@ -156,6 +156,24 @@ g_strv_builder_add_many (GStrvBuilder *builder, va_end (var_args); } +/** + * g_strv_builder_take: + * @builder: a #GStrvBuilder + * @value: (transfer full): a string. + * Ownership of the string is transferred to the #GStrvBuilder + * + * Add a string to the end of the array. After @value belongs to the + * #GStrvBuilder and may no longer be modified by the caller. + * + * Since 2.80 + */ +void +g_strv_builder_take (GStrvBuilder *builder, + char *value) +{ + g_ptr_array_add (&builder->array, value); +} + /** * g_strv_builder_end: * @builder: a #GStrvBuilder diff --git a/glib/gstrvbuilder.h b/glib/gstrvbuilder.h index af5451c36..f96df3002 100644 --- a/glib/gstrvbuilder.h +++ b/glib/gstrvbuilder.h @@ -53,6 +53,10 @@ GLIB_AVAILABLE_IN_2_70 void g_strv_builder_add_many (GStrvBuilder *builder, ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_2_80 +void g_strv_builder_take (GStrvBuilder *builder, + char *value); + GLIB_AVAILABLE_IN_2_68 GStrv g_strv_builder_end (GStrvBuilder *builder); diff --git a/glib/tests/strvbuilder.c b/glib/tests/strvbuilder.c index 595a6845e..ed0cfa352 100644 --- a/glib/tests/strvbuilder.c +++ b/glib/tests/strvbuilder.c @@ -92,6 +92,25 @@ test_strvbuilder_add_many (void) g_strv_builder_unref (builder); } +static void +test_strvbuilder_take (void) +{ + GStrvBuilder *builder; + GStrv result; + const gchar *expected[] = { "one", "two", "three", NULL }; + + builder = g_strv_builder_new (); + g_strv_builder_take (builder, g_strdup ("one")); + g_strv_builder_add (builder, "two"); + g_strv_builder_take (builder, g_strdup ("three")); + result = g_strv_builder_end (builder); + g_assert_nonnull (result); + g_assert_true (g_strv_equal ((const gchar *const *) result, expected)); + + g_strfreev (result); + g_strv_builder_unref (builder); +} + static void test_strvbuilder_ref (void) { @@ -113,6 +132,7 @@ main (int argc, g_test_add_func ("/strvbuilder/add", test_strvbuilder_add); g_test_add_func ("/strvbuilder/addv", test_strvbuilder_addv); g_test_add_func ("/strvbuilder/add_many", test_strvbuilder_add_many); + g_test_add_func ("/strvbuilder/take", test_strvbuilder_take); g_test_add_func ("/strvbuilder/ref", test_strvbuilder_ref); return g_test_run ();