summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kost <ensonic@users.sf.net>2009-06-02 18:36:10 +0300
committerStefan Kost <ensonic@users.sf.net>2009-06-02 18:39:17 +0300
commit47d9904ebab49e362c464ef48271ebdb54cde94c (patch)
treecd1152df5d2d4c72a4847d3eebe58428f4cb0919
parent71a5ebe638ed611d488c9ffedbf03b7cf9c14dac (diff)
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.
-rw-r--r--gst/gst_private.h7
-rw-r--r--gst/gststructure.c13
-rw-r--r--gst/gstvalue.c21
-rw-r--r--tests/check/gst/gststructure.c53
4 files changed, 68 insertions, 26 deletions
diff --git a/gst/gst_private.h b/gst/gst_private.h
index c54bf19dd2..553f7161c8 100644
--- a/gst/gst_private.h
+++ b/gst/gst_private.h
@@ -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
diff --git a/gst/gststructure.c b/gst/gststructure.c
index a43b9e7a8c..e668762006 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -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)
diff --git a/gst/gstvalue.c b/gst/gstvalue.c
index 7286a97c11..8cbb61d406 100644
--- a/gst/gstvalue.c
+++ b/gst/gstvalue.c
@@ -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)
{
diff --git a/tests/check/gst/gststructure.c b/tests/check/gst/gststructure.c
index e2cf577ff6..3d84057e00 100644
--- a/tests/check/gst/gststructure.c
+++ b/tests/check/gst/gststructure.c
@@ -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;
}