mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 08:08:22 +00:00
structure: fix serialisation of nested structures.
Use string_warp/unwrap to escape delimiters, otherwise deserialisation fails. Also move GST_ASCII_IS_STRING to private header to avoid keeping it in sync. Also use '\0' when terminating a string for better readability.
This commit is contained in:
parent
71a5ebe638
commit
47d9904eba
4 changed files with 68 additions and 26 deletions
|
@ -20,7 +20,6 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_PRIVATE_H__
|
#ifndef __GST_PRIVATE_H__
|
||||||
#define __GST_PRIVATE_H__
|
#define __GST_PRIVATE_H__
|
||||||
|
|
||||||
|
@ -109,6 +108,12 @@ gboolean priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
||||||
gboolean gst_registry_binary_read_cache (GstRegistry * registry, const char *location);
|
gboolean gst_registry_binary_read_cache (GstRegistry * registry, const char *location);
|
||||||
gboolean gst_registry_binary_write_cache (GstRegistry * registry, const char *location);
|
gboolean gst_registry_binary_write_cache (GstRegistry * registry, const char *location);
|
||||||
|
|
||||||
|
|
||||||
|
/* used in gstvalue.c and gststructure.c */
|
||||||
|
#define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
|
||||||
|
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
|
||||||
|
((c) == '.'))
|
||||||
|
|
||||||
/*** debugging categories *****************************************************/
|
/*** debugging categories *****************************************************/
|
||||||
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
|
|
@ -1560,11 +1560,6 @@ gst_structure_value_get_generic_type (GValue * val)
|
||||||
return G_VALUE_TYPE (val);
|
return G_VALUE_TYPE (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep in sync with gstvalue.c */
|
|
||||||
#define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
|
|
||||||
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
|
|
||||||
((c) == '.'))
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
priv_gst_structure_append_to_gstring (const GstStructure * structure,
|
||||||
GString * s)
|
GString * s)
|
||||||
|
@ -1853,7 +1848,7 @@ gst_structure_parse_field (gchar * str,
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
c = *name_end;
|
c = *name_end;
|
||||||
*name_end = 0;
|
*name_end = '\0';
|
||||||
field->name = g_quark_from_string (name);
|
field->name = g_quark_from_string (name);
|
||||||
*name_end = c;
|
*name_end = c;
|
||||||
|
|
||||||
|
@ -1877,7 +1872,6 @@ gst_structure_parse_value (gchar * str,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
GType type = default_type;
|
GType type = default_type;
|
||||||
|
|
||||||
|
|
||||||
s = str;
|
s = str;
|
||||||
while (g_ascii_isspace (*s))
|
while (g_ascii_isspace (*s))
|
||||||
s++;
|
s++;
|
||||||
|
@ -1923,7 +1917,7 @@ gst_structure_parse_value (gchar * str,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
c = *value_end;
|
c = *value_end;
|
||||||
*value_end = 0;
|
*value_end = '\0';
|
||||||
if (type == G_TYPE_INVALID) {
|
if (type == G_TYPE_INVALID) {
|
||||||
GType try_types[] =
|
GType try_types[] =
|
||||||
{ G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
|
{ G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
|
||||||
|
@ -1991,7 +1985,7 @@ gst_structure_from_string (const gchar * string, gchar ** end)
|
||||||
}
|
}
|
||||||
|
|
||||||
save = *w;
|
save = *w;
|
||||||
*w = 0;
|
*w = '\0';
|
||||||
structure = gst_structure_empty_new (name);
|
structure = gst_structure_empty_new (name);
|
||||||
*w = save;
|
*w = save;
|
||||||
|
|
||||||
|
@ -2024,7 +2018,6 @@ gst_structure_from_string (const gchar * string, gchar ** end)
|
||||||
if (!gst_structure_parse_field (r, &r, &field))
|
if (!gst_structure_parse_field (r, &r, &field))
|
||||||
goto error;
|
goto error;
|
||||||
gst_structure_set_field (structure, &field);
|
gst_structure_set_field (structure, &field);
|
||||||
|
|
||||||
} while (TRUE);
|
} while (TRUE);
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
|
|
|
@ -80,6 +80,9 @@ static GstValueCompareFunc gst_value_get_compare_func (const GValue * value1);
|
||||||
static gint gst_value_compare_with_func (const GValue * value1,
|
static gint gst_value_compare_with_func (const GValue * value1,
|
||||||
const GValue * value2, GstValueCompareFunc compare);
|
const GValue * value2, GstValueCompareFunc compare);
|
||||||
|
|
||||||
|
static gchar *gst_string_wrap (const gchar * s);
|
||||||
|
static gchar *gst_string_unwrap (const gchar * s);
|
||||||
|
|
||||||
/********
|
/********
|
||||||
* list *
|
* list *
|
||||||
********/
|
********/
|
||||||
|
@ -1335,7 +1338,7 @@ gst_value_serialize_structure (const GValue * value)
|
||||||
{
|
{
|
||||||
GstStructure *structure = g_value_get_boxed (value);
|
GstStructure *structure = g_value_get_boxed (value);
|
||||||
|
|
||||||
return gst_structure_to_string (structure);
|
return gst_string_wrap (gst_structure_to_string (structure));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1343,7 +1346,16 @@ gst_value_deserialize_structure (GValue * dest, const gchar * s)
|
||||||
{
|
{
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
|
|
||||||
structure = gst_structure_from_string (s, NULL);
|
if (*s != '"') {
|
||||||
|
structure = gst_structure_from_string (s, NULL);
|
||||||
|
} else {
|
||||||
|
gchar *str = gst_string_unwrap (s);
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
structure = gst_structure_from_string (str, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (structure) {
|
if (structure) {
|
||||||
g_value_set_boxed (dest, structure);
|
g_value_set_boxed (dest, structure);
|
||||||
|
@ -1777,11 +1789,6 @@ gst_value_compare_string (const GValue * value1, const GValue * value2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep in sync with gststructure.c */
|
|
||||||
#define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
|
|
||||||
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
|
|
||||||
((c) == '.'))
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
gst_string_wrap (const gchar * s)
|
gst_string_wrap (const gchar * s)
|
||||||
{
|
{
|
||||||
|
|
|
@ -349,30 +349,33 @@ GST_START_TEST (test_structure_nested)
|
||||||
GstStructure *sp, *sc1, *sc2;
|
GstStructure *sp, *sc1, *sc2;
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
sc1 =
|
sc1 = gst_structure_new ("Camera",
|
||||||
gst_structure_new ("Camera", "XResolution", G_TYPE_INT, 72, "YResolution",
|
"XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
|
||||||
G_TYPE_INT, 73, NULL);
|
|
||||||
fail_unless (sc1 != NULL);
|
fail_unless (sc1 != NULL);
|
||||||
|
|
||||||
sc2 =
|
sc2 = gst_structure_new ("Image-Data",
|
||||||
gst_structure_new ("Image-Data", "Orientation", G_TYPE_STRING, "top-left",
|
"Orientation", G_TYPE_STRING, "top-left",
|
||||||
NULL);
|
"Comment", G_TYPE_STRING, "super photo", NULL);
|
||||||
fail_unless (sc2 != NULL);
|
fail_unless (sc2 != NULL);
|
||||||
|
|
||||||
sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
|
sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
|
||||||
"Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
|
"Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
|
||||||
fail_unless (sp != NULL);
|
fail_unless (sp != NULL);
|
||||||
|
|
||||||
|
fail_unless (gst_structure_n_fields (sp) == 2);
|
||||||
|
|
||||||
fail_unless (gst_structure_has_field_typed (sp, "Camera",
|
fail_unless (gst_structure_has_field_typed (sp, "Camera",
|
||||||
GST_TYPE_STRUCTURE));
|
GST_TYPE_STRUCTURE));
|
||||||
|
|
||||||
str = gst_structure_to_string (sp);
|
str = gst_structure_to_string (sp);
|
||||||
fail_unless (str != NULL);
|
fail_unless (str != NULL);
|
||||||
|
|
||||||
|
GST_DEBUG ("serialized to '%s'", str);
|
||||||
|
|
||||||
fail_unless (g_str_equal (str,
|
fail_unless (g_str_equal (str,
|
||||||
"Exif"
|
"Exif"
|
||||||
", Camera=(structure)Camera, XResolution=(int)72, YResolution=(int)73;"
|
", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
|
||||||
", Image Data=(structure)Image-Data, Orientation=(string)top-left;;"));
|
", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
|
||||||
|
|
||||||
g_free (str);
|
g_free (str);
|
||||||
str = NULL;
|
str = NULL;
|
||||||
|
@ -380,7 +383,40 @@ GST_START_TEST (test_structure_nested)
|
||||||
gst_structure_free (sc1);
|
gst_structure_free (sc1);
|
||||||
gst_structure_free (sc2);
|
gst_structure_free (sc2);
|
||||||
gst_structure_free (sp);
|
gst_structure_free (sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_structure_nested_from_and_to_string)
|
||||||
|
{
|
||||||
|
GstStructure *s;
|
||||||
|
gchar *str1, *str2, *end = NULL;
|
||||||
|
|
||||||
|
str1 = "main"
|
||||||
|
", main-sub1=(structure)\"type-b\\,\\ machine-type\\=\\(int\\)0\\;\""
|
||||||
|
", main-sub2=(structure)\"type-a\\,\\ plugin-filename\\=\\(string\\)\\\"/home/user/lib/lib\\\\\\ with\\\\\\ spaces.dll\\\"\\,\\ machine-type\\=\\(int\\)1\\;\""
|
||||||
|
", main-sub3=(structure)\"type-b\\,\\ plugin-filename\\=\\(string\\)/home/user/lib/lib_no_spaces.so\\,\\ machine-type\\=\\(int\\)1\\;\""
|
||||||
|
";";
|
||||||
|
|
||||||
|
s = gst_structure_from_string (str1, &end);
|
||||||
|
fail_unless (s != NULL);
|
||||||
|
|
||||||
|
GST_DEBUG ("not parsed part : %s", end);
|
||||||
|
fail_unless (*end == '\0');
|
||||||
|
|
||||||
|
fail_unless (gst_structure_n_fields (s) == 3);
|
||||||
|
|
||||||
|
fail_unless (gst_structure_has_field_typed (s, "main-sub1",
|
||||||
|
GST_TYPE_STRUCTURE));
|
||||||
|
|
||||||
|
str2 = gst_structure_to_string (s);
|
||||||
|
fail_unless (str2 != NULL);
|
||||||
|
|
||||||
|
fail_unless (g_str_equal (str1, str2));
|
||||||
|
|
||||||
|
g_free (str2);
|
||||||
|
|
||||||
|
gst_structure_free (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -413,6 +449,7 @@ gst_structure_suite (void)
|
||||||
tcase_add_test (tc_chain, test_fixate);
|
tcase_add_test (tc_chain, test_fixate);
|
||||||
tcase_add_test (tc_chain, test_fixate_frac_list);
|
tcase_add_test (tc_chain, test_fixate_frac_list);
|
||||||
tcase_add_test (tc_chain, test_structure_nested);
|
tcase_add_test (tc_chain, test_structure_nested);
|
||||||
|
tcase_add_test (tc_chain, test_structure_nested_from_and_to_string);
|
||||||
tcase_add_test (tc_chain, test_empty_string_fields);
|
tcase_add_test (tc_chain, test_empty_string_fields);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue