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:
Stefan Kost 2009-06-02 18:36:10 +03:00
parent 71a5ebe638
commit 47d9904eba
4 changed files with 68 additions and 26 deletions

View file

@ -20,7 +20,6 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef __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_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 *****************************************************/
#ifndef GST_DISABLE_GST_DEBUG

View file

@ -1560,11 +1560,6 @@ gst_structure_value_get_generic_type (GValue * 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
priv_gst_structure_append_to_gstring (const GstStructure * structure,
GString * s)
@ -1853,7 +1848,7 @@ gst_structure_parse_field (gchar * str,
s++;
c = *name_end;
*name_end = 0;
*name_end = '\0';
field->name = g_quark_from_string (name);
*name_end = c;
@ -1877,7 +1872,6 @@ gst_structure_parse_value (gchar * str,
int ret = 0;
GType type = default_type;
s = str;
while (g_ascii_isspace (*s))
s++;
@ -1923,7 +1917,7 @@ gst_structure_parse_value (gchar * str,
return FALSE;
c = *value_end;
*value_end = 0;
*value_end = '\0';
if (type == G_TYPE_INVALID) {
GType try_types[] =
{ 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;
*w = 0;
*w = '\0';
structure = gst_structure_empty_new (name);
*w = save;
@ -2024,7 +2018,6 @@ gst_structure_from_string (const gchar * string, gchar ** end)
if (!gst_structure_parse_field (r, &r, &field))
goto error;
gst_structure_set_field (structure, &field);
} while (TRUE);
if (end)

View file

@ -80,6 +80,9 @@ static GstValueCompareFunc gst_value_get_compare_func (const GValue * value1);
static gint gst_value_compare_with_func (const GValue * value1,
const GValue * value2, GstValueCompareFunc compare);
static gchar *gst_string_wrap (const gchar * s);
static gchar *gst_string_unwrap (const gchar * s);
/********
* list *
********/
@ -1335,7 +1338,7 @@ gst_value_serialize_structure (const GValue * 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
@ -1343,7 +1346,16 @@ gst_value_deserialize_structure (GValue * dest, const gchar * s)
{
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) {
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 *
gst_string_wrap (const gchar * s)
{

View file

@ -349,30 +349,33 @@ GST_START_TEST (test_structure_nested)
GstStructure *sp, *sc1, *sc2;
gchar *str;
sc1 =
gst_structure_new ("Camera", "XResolution", G_TYPE_INT, 72, "YResolution",
G_TYPE_INT, 73, NULL);
sc1 = gst_structure_new ("Camera",
"XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
fail_unless (sc1 != NULL);
sc2 =
gst_structure_new ("Image-Data", "Orientation", G_TYPE_STRING, "top-left",
NULL);
sc2 = gst_structure_new ("Image-Data",
"Orientation", G_TYPE_STRING, "top-left",
"Comment", G_TYPE_STRING, "super photo", NULL);
fail_unless (sc2 != NULL);
sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
"Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
fail_unless (sp != NULL);
fail_unless (gst_structure_n_fields (sp) == 2);
fail_unless (gst_structure_has_field_typed (sp, "Camera",
GST_TYPE_STRUCTURE));
str = gst_structure_to_string (sp);
fail_unless (str != NULL);
GST_DEBUG ("serialized to '%s'", str);
fail_unless (g_str_equal (str,
"Exif"
", Camera=(structure)Camera, XResolution=(int)72, YResolution=(int)73;"
", Image Data=(structure)Image-Data, Orientation=(string)top-left;;"));
", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
g_free (str);
str = NULL;
@ -380,7 +383,40 @@ GST_START_TEST (test_structure_nested)
gst_structure_free (sc1);
gst_structure_free (sc2);
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;
@ -413,6 +449,7 @@ gst_structure_suite (void)
tcase_add_test (tc_chain, test_fixate);
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_from_and_to_string);
tcase_add_test (tc_chain, test_empty_string_fields);
return s;
}