summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2023-05-16 12:04:37 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2023-05-16 12:04:37 +0000
commitec8856d7d69be85bc1ad3c64a801460c8c692231 (patch)
treeb220a46f844450a687d9f772967a779bbb01f9ff
parent90c3438373645033782eb9a326d4417f6c4f0888 (diff)
parentac4d1e2686fa6580f070b4aba9cd6423b691c7e3 (diff)
downloadglib-ec8856d7d69be85bc1ad3c64a801460c8c692231.tar.gz
Merge branch 'wip/p3732/g-string-new-steal' into 'main'
gstring: add g_string_new_take See merge request GNOME/glib!3423
-rw-r--r--docs/reference/glib/glib-sections.txt.in1
-rw-r--r--glib/garray.c30
-rw-r--r--glib/gbytes.c8
-rw-r--r--glib/gstring.c33
-rw-r--r--glib/gstring.h2
-rw-r--r--glib/gvariant.c5
-rw-r--r--glib/tests/string.c36
7 files changed, 98 insertions, 17 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/garray.c b/glib/garray.c
index 118360ca1..4e8c8c309 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -204,8 +204,10 @@ g_array_new (gboolean zero_terminated,
* reference count of 1.
*
* This avoids having to copy the data manually, when it can just be
- * inherited. @data will eventually be freed using g_free(), so must
- * have been allocated with a suitable allocator.
+ * inherited.
+ * After this call, @data belongs to the #GArray 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().
*
* In case the elements need to be cleared when the array is freed, use
* g_array_set_clear_func() to set a #GDestroyNotify function to perform
@@ -252,8 +254,10 @@ g_array_new_take (gpointer data,
* and setting the reference count to 1.
*
* This avoids having to copy the data manually, when it can just be
- * inherited. @data will eventually be freed using g_free(), so must
- * have been allocated with a suitable allocator.
+ * inherited.
+ * After this call, @data belongs to the #GArray 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().
*
* The length is calculated by iterating through @data until the first %NULL
* element is found.
@@ -1275,8 +1279,10 @@ g_ptr_array_new (void)
* Creates a new #GPtrArray with @data as pointers, @len as length and a
* reference count of 1.
*
- * This avoids having to copy such data manually. @data will eventually be
- * freed using g_free(), so must have been allocated with a suitable allocator.
+ * This avoids having to copy such data manually.
+ * After this call, @data belongs to the #GPtrArray 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().
*
* It also sets @element_free_func for freeing each element when the array is
* destroyed either via g_ptr_array_unref(), when g_ptr_array_free() is called
@@ -1321,8 +1327,10 @@ g_ptr_array_new_take (gpointer *data,
* Creates a new #GPtrArray with @data as pointers, computing the length of it
* and setting the reference count to 1.
*
- * This avoids having to copy such data manually. @data will eventually be
- * freed using g_free(), so must have been allocated with a suitable allocator.
+ * This avoids having to copy such data manually.
+ * After this call, @data belongs to the #GPtrArray 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().
*
* The length is calculated by iterating through @data until the first %NULL
* element is found.
@@ -2845,8 +2853,10 @@ g_byte_array_steal (GByteArray *array,
* @data: (transfer full) (array length=len): byte data for the array
* @len: length of @data
*
- * Create byte array containing the data. The data will be owned by the array
- * and will be freed with g_free(), i.e. it could be allocated using g_strdup().
+ * Creates a byte array containing the @data.
+ * After this call, @data belongs to the #GByteArray 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().
*
* Do not use it if @len is greater than %G_MAXUINT. #GByteArray
* stores the length of its data in #guint, which may be shorter than
diff --git a/glib/gbytes.c b/glib/gbytes.c
index e4d269710..380e39f96 100644
--- a/glib/gbytes.c
+++ b/glib/gbytes.c
@@ -108,11 +108,9 @@ g_bytes_new (gconstpointer data,
*
* Creates a new #GBytes from @data.
*
- * After this call, @data belongs to the bytes and may no longer be
- * modified by the caller. g_free() will be called on @data when the
- * bytes is no longer in use. Because of this @data must have been created by
- * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many
- * functions that wrap these calls (such as g_new(), g_strdup(), etc).
+ * After this call, @data belongs to the #GBytes 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().
*
* For creating #GBytes with memory from other allocators, see
* g_bytes_new_with_free_func().
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/gvariant.c b/glib/gvariant.c
index 40cda9c9d..b7e42413c 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -1282,8 +1282,9 @@ g_variant_new_string (const gchar *string)
* @string must be valid UTF-8, and must not be %NULL. To encode
* potentially-%NULL strings, use this with g_variant_new_maybe().
*
- * This function consumes @string. g_free() will be called on @string
- * when it is no longer required.
+ * After this call, @string belongs to the #GVariant 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().
*
* You must not modify or access @string in any other way after passing
* it to this function. It is even possible that @string is immediately
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();
}