summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisenmann <p3732@getgoogleoff.me>2023-05-02 13:07:13 +0200
committerPhilip Withnall <pwithnall@endlessos.org>2023-05-16 11:27:45 +0100
commitafdab4f493493ab5631f6376455f34812a859030 (patch)
tree8748183de4cc8b1a493f9e307712b3b56d1ed6e9
parent03aa8513f8591892fd5cc09b4fa068ba1bfc2667 (diff)
downloadglib-afdab4f493493ab5631f6376455f34812a859030.tar.gz
gstring: add g_string_new_take
Adds a GString constructor that takes over ownership of an existing, dynamically allocated, string.
-rw-r--r--docs/reference/glib/glib-sections.txt.in1
-rw-r--r--glib/gstring.c33
-rw-r--r--glib/gstring.h2
-rw-r--r--glib/tests/string.c36
4 files changed, 72 insertions, 0 deletions
diff --git a/docs/reference/glib/glib-sections.txt.in b/docs/reference/glib/glib-sections.txt.in
index 60e87af5b..d9e7ac3d6 100644
--- a/docs/reference/glib/glib-sections.txt.in
+++ b/docs/reference/glib/glib-sections.txt.in
@@ -2625,6 +2625,7 @@ g_str_hash
<FILE>strings</FILE>
GString
g_string_new
+g_string_new_take
g_string_new_len
g_string_sized_new
g_string_assign
diff --git a/glib/gstring.c b/glib/gstring.c
index ad6b92231..77448f2f1 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -156,6 +156,39 @@ g_string_new (const gchar *init)
}
/**
+ * g_string_new_take: (constructor)
+ * @init: (nullable) (transfer full): initial text used as the string.
+ * Ownership of the string is transferred to the #GString.
+ * Passing %NULL creates an empty string.
+ *
+ * Creates a new #GString, initialized with the given string.
+ *
+ * After this call, @init belongs to the #GString and may no longer be
+ * modified by the caller. The memory of @data has to be dynamically
+ * allocated and will eventually be freed with g_free().
+ *
+ * Returns: (transfer full): the new #GString
+ */
+GString *
+g_string_new_take (gchar *init)
+{
+ GString *string;
+
+ if (init == NULL)
+ {
+ return g_string_new (NULL);
+ }
+
+ string = g_slice_new (GString);
+
+ string->str = init;
+ string->len = strlen (string->str);
+ string->allocated_len = string->len + 1;
+
+ return string;
+}
+
+/**
* g_string_new_len: (constructor)
* @init: initial contents of the string
* @len: length of @init to use
diff --git a/glib/gstring.h b/glib/gstring.h
index 859668716..b4ccb34a9 100644
--- a/glib/gstring.h
+++ b/glib/gstring.h
@@ -51,6 +51,8 @@ struct _GString
GLIB_AVAILABLE_IN_ALL
GString* g_string_new (const gchar *init);
+GLIB_AVAILABLE_IN_2_78
+GString* g_string_new_take (gchar *init);
GLIB_AVAILABLE_IN_ALL
GString* g_string_new_len (const gchar *init,
gssize len);
diff --git a/glib/tests/string.c b/glib/tests/string.c
index a2225189f..932a311de 100644
--- a/glib/tests/string.c
+++ b/glib/tests/string.c
@@ -709,6 +709,40 @@ test_string_steal (void)
g_free (str);
}
+static void
+test_string_new_take (void)
+{
+ const char *test_str_const = "test_test";
+ const char *replaced_str_const = "test__test";
+ char *test_str = malloc (10 * sizeof (*test_str_const));
+ GString *string;
+
+ strcpy (test_str, test_str_const);
+ g_assert_cmpstr (test_str, ==, test_str_const);
+
+ string = g_string_new_take (g_steal_pointer (&test_str));
+ g_assert_null (test_str);
+ g_assert_nonnull (string);
+
+ g_string_replace (string, "_", "__", 0);
+ g_assert_cmpstr (string->str, ==, replaced_str_const);
+
+ test_str = g_string_free_and_steal (g_steal_pointer (&string));
+ g_assert_cmpstr (test_str, ==, replaced_str_const);
+
+ g_free (test_str);
+}
+
+static void
+test_string_new_take_null (void)
+{
+ GString *string = g_string_new_take (NULL);
+
+ g_assert_cmpstr (string->str, ==, "");
+
+ g_string_free (g_steal_pointer (&string), TRUE);
+}
+
int
main (int argc,
char *argv[])
@@ -736,6 +770,8 @@ main (int argc,
g_test_add_func ("/string/test-string-to-bytes", test_string_to_bytes);
g_test_add_func ("/string/test-string-replace", test_string_replace);
g_test_add_func ("/string/test-string-steal", test_string_steal);
+ g_test_add_func ("/string/test-string-new-take", test_string_new_take);
+ g_test_add_func ("/string/test-string-new-take/null", test_string_new_take_null);
return g_test_run();
}