Merge branch 'gvalue-steal-string' into 'main'

gvalue: add "steal_string"

See merge request GNOME/glib!3695
This commit is contained in:
Philip Withnall 2023-11-04 11:05:47 +00:00
commit 734f8184e8
4 changed files with 60 additions and 1 deletions

View File

@ -719,6 +719,7 @@ g_value_take_string
g_value_set_string_take_ownership
g_value_get_string
g_value_dup_string
g_value_steal_string
g_value_set_interned_string
<SUBSECTION GParamSpec>

View File

@ -1159,6 +1159,41 @@ g_value_dup_string (const GValue *value)
return g_strdup (value->data[0].v_pointer);
}
/**
* g_value_steal_string:
* @value: a valid #GValue of type %G_TYPE_STRING
*
* Steal ownership on contents of a %G_TYPE_STRING #GValue.
* As a result of this operation the value's contents will be reset to %NULL.
*
* The purpose of this call is to provide a way to avoid an extra copy
* when some object have been serialized into string through #GValue API.
*
* NOTE: for safety and compatibility purposes, if #GValue contains
* static string, or an interned one, this function will return a copy
* of the string. Otherwise the transfer notation would be ambiguous.
*
* Returns: (nullable) (transfer full): string content of @value;
* Should be freed with g_free() when no longer needed.
*
* Since: 2.80
*/
gchar*
g_value_steal_string (GValue *value)
{
gchar *ret;
g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
ret = value->data[0].v_pointer;
value->data[0].v_pointer = NULL;
if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
return g_strdup (ret);
return ret;
}
/**
* g_value_set_pointer:
* @value: a valid #GValue of %G_TYPE_POINTER

View File

@ -263,6 +263,8 @@ GOBJECT_AVAILABLE_IN_ALL
const gchar * g_value_get_string (const GValue *value);
GOBJECT_AVAILABLE_IN_ALL
gchar* g_value_dup_string (const GValue *value);
GOBJECT_AVAILABLE_IN_2_80
gchar* g_value_steal_string (GValue *value);
GOBJECT_AVAILABLE_IN_ALL
void g_value_set_pointer (GValue *value,
gpointer v_pointer);

View File

@ -420,7 +420,7 @@ test_value_string (void)
const gchar *static2 = "static2";
const gchar *storedstr;
const gchar *copystr;
gchar *str1, *str2;
gchar *str1, *str2, *stolen_str;
GValue value = G_VALUE_INIT;
GValue copy = G_VALUE_INIT;
@ -513,7 +513,12 @@ test_value_string (void)
g_assert_true (storedstr != static2);
g_assert_cmpstr (storedstr, ==, static2);
/* Now check stealing the ownership of the contents */
stolen_str = g_value_steal_string (&value);
g_assert_null (g_value_get_string (&value));
g_value_unset (&value);
g_assert_cmpstr (stolen_str, ==, static2);
g_free (stolen_str);
/*
* Static strings
@ -544,6 +549,14 @@ test_value_string (void)
g_assert_true (storedstr != static1);
g_assert_cmpstr (storedstr, ==, static2);
/* Check if g_value_steal_string() can handle GValue
* with a static string */
stolen_str = g_value_steal_string (&value);
g_assert_true (stolen_str != static2);
g_assert_cmpstr (stolen_str, ==, static2);
g_assert_null (g_value_get_string (&value));
g_free (stolen_str);
g_value_unset (&value);
/*
@ -588,6 +601,14 @@ test_value_string (void)
g_assert_true (storedstr != static2);
g_assert_cmpstr (storedstr, ==, static2);
/* Check if g_value_steal_string() can handle GValue
* with an interned string */
stolen_str = g_value_steal_string (&value);
g_assert_true (stolen_str != static2);
g_assert_cmpstr (stolen_str, ==, static2);
g_assert_null (g_value_get_string (&value));
g_free (stolen_str);
g_value_unset (&value);
}