gststructure: Fix deserialization of GStrv

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8438>
This commit is contained in:
Xavier Claessens 2025-02-13 09:54:43 -05:00 committed by GStreamer Marge Bot
parent e06e977304
commit f25668a223
4 changed files with 61 additions and 10 deletions

View File

@ -42701,6 +42701,9 @@ Some types have special delimiters:
`a-structure, a-int64-range=(gint64) [1, 5]`
- [GstValueList](GST_TYPE_LIST) are inside curly brackets (`{` and `}`).
For example `a-structure, list={1, 2, 3}`
- [GStrv](G_TYPE_STRV) are inside "less and greater than" (`&lt;` and
`&gt;`) and each string is double-quoted.
For example `a-structure, strv=(GStrv)&lt;"foo", "bar"&gt;`. Since 1.26.0.
Structures are delimited either by a null character `\0` or a semicolon `;`
the latter allowing to store multiple structures in the same string (see

View File

@ -98,6 +98,9 @@
* `a-structure, a-int64-range=(gint64) [1, 5]`
* - [GstValueList](GST_TYPE_LIST) are inside curly brackets (`{` and `}`).
* For example `a-structure, list={1, 2, 3}`
* - [GStrv](G_TYPE_STRV) are inside "less and greater than" (`<` and
* `>`) and each string is double-quoted.
* For example `a-structure, strv=(GStrv)<"foo", "bar">`. Since 1.26.0.
*
* Structures are delimited either by a null character `\0` or a semicolon `;`
* the latter allowing to store multiple structures in the same string (see

View File

@ -100,6 +100,8 @@ static gboolean _priv_gst_value_parse_list (gchar * s, gchar ** after,
GValue * value, GType type, GParamSpec * pspec);
static gboolean _priv_gst_value_parse_array (gchar * s, gchar ** after,
GValue * value, GType type, GParamSpec * pspec);
static gboolean _priv_gst_value_parse_strv (const gchar * s,
const gchar ** after, GValue * dest);
typedef struct _GstValueUnionInfo GstValueUnionInfo;
struct _GstValueUnionInfo
@ -2811,8 +2813,13 @@ _priv_gst_value_parse_value (gchar * str,
g_value_init (value, GST_TYPE_LIST);
ret = _priv_gst_value_parse_list (s, &s, value, type, pspec);
} else if (*s == '<') {
g_value_init (value, GST_TYPE_ARRAY);
ret = _priv_gst_value_parse_array (s, &s, value, type, pspec);
if (type == G_TYPE_STRV) {
g_value_init (value, G_TYPE_STRV);
ret = _priv_gst_value_parse_strv (s, (const gchar **) &s, value);
} else {
g_value_init (value, GST_TYPE_ARRAY);
ret = _priv_gst_value_parse_array (s, &s, value, type, pspec);
}
} else {
value_s = s;
@ -8171,15 +8178,13 @@ gst_value_serialize_strv (const GValue * value)
}
static gboolean
gst_value_deserialize_strv (GValue * dest, const gchar * s)
_priv_gst_value_parse_strv (const gchar * s, const gchar ** after,
GValue * dest)
{
/* If it's not starting with '<' assume it's a simple comma separated list
* with no escaping. Otherwise assume the format <"foo","bar"> with spaces
* allowed between delimiters and \ for escaping. */
if (*s != '<') {
g_value_take_boxed (dest, g_strsplit (s, ",", -1));
return TRUE;
}
/* Parse the format <"foo","bar"> with spaces allowed between delimiters,
* and \ for escaping. */
if (*s != '<')
return FALSE;
s++;
while (g_ascii_isspace (*s))
@ -8235,6 +8240,8 @@ gst_value_deserialize_strv (GValue * dest, const gchar * s)
g_ptr_array_add (strv, NULL);
g_value_take_boxed (dest, g_ptr_array_free (strv, FALSE));
*after = s + 1;
return TRUE;
error:
@ -8242,6 +8249,18 @@ error:
return FALSE;
}
static gboolean
gst_value_deserialize_strv (GValue * dest, const gchar * s)
{
/* If it's not starting with '<' assume it's a simple comma separated list
* with no escaping. This makes usage in gst-launch-1.0 easier. */
if (*s != '<') {
g_value_take_boxed (dest, g_strsplit (s, ",", -1));
return TRUE;
}
return _priv_gst_value_parse_strv (s, &s, dest);
}
static GTypeInfo _info = {
0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL,
};

View File

@ -1169,6 +1169,31 @@ GST_START_TEST (test_strict)
GST_END_TEST;
GST_START_TEST (test_strv)
{
GstStructure *s;
const gchar *strv[] = { "foo", " ,<>\" ", NULL };
s = gst_structure_new ("test-struct", "strv", G_TYPE_STRV, strv, NULL);
fail_unless (s);
gchar *serialized = gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_NONE);
fail_unless (serialized);
gst_structure_free (s);
s = gst_structure_new_from_string (serialized);
fail_unless (s);
g_free (serialized);
gchar **out_strv = NULL;
fail_unless (gst_structure_get (s, "strv", G_TYPE_STRV, &out_strv, NULL));
fail_unless (g_strv_equal (strv, (const gchar * const *) out_strv));
gst_structure_free (s);
g_strfreev (out_strv);
}
GST_END_TEST;
static Suite *
gst_structure_suite (void)
{
@ -1203,6 +1228,7 @@ gst_structure_suite (void)
tcase_add_test (tc_chain, test_flagset);
tcase_add_test (tc_chain, test_flags);
tcase_add_test (tc_chain, test_strict);
tcase_add_test (tc_chain, test_strv);
return s;
}