From 0e3a0fdf35bbfbcba69d47b3c02556c3c7b56eae Mon Sep 17 00:00:00 2001 From: Edgard Lima Date: Mon, 22 Oct 2007 08:53:26 +0000 Subject: [PATCH] Added GstStructure to gst_value_table and its related functions. Original commit message from CVS: * gst/gstcaps.c: (gst_caps_to_string), (gst_caps_from_string_inplace): * gst/gststructure.c: (gst_structure_get_abbrs), (gst_structure_to_string), (gst_structure_from_string): * gst/gstvalue.c: (gst_value_set_structure), (gst_value_get_structure), (gst_value_serialize_structure), (gst_value_deserialize_structure), (_gst_value_initialize): * gst/gstvalue.h: * tests/check/gst/gststructure.c: (GST_START_TEST), (gst_structure_suite): * tests/check/gst/gstvalue.c: (GST_START_TEST): Added GstStructure to gst_value_table and its related functions. Changed gst_structure_to_string to print ';' in the end. Changed gst_caps_to_string to not print ';' beteween its fields (structures) anymore and remove the lastes ';' from latest structure. Now it is possible to have nested structures. In addition, backward compatibilty is assured by accepting '\0' as end delimiter. Fixes: #487969. API: add gst_value_set_structure() API: add gst_value_get_structure() --- ChangeLog | 24 ++++++++++++ gst/gstcaps.c | 24 +++++++----- gst/gststructure.c | 38 ++++++++++++------- gst/gstvalue.c | 67 ++++++++++++++++++++++++++++++++++ gst/gstvalue.h | 15 ++++++++ tests/check/gst/gststructure.c | 42 +++++++++++++++++++++ tests/check/gst/gstvalue.c | 4 +- 7 files changed, 189 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6d9bb37d4..d79d8b9291 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2007-10-22 Edgard Lima + + * gst/gstcaps.c: (gst_caps_to_string), + (gst_caps_from_string_inplace): + * gst/gststructure.c: (gst_structure_get_abbrs), + (gst_structure_to_string), (gst_structure_from_string): + * gst/gstvalue.c: (gst_value_set_structure), + (gst_value_get_structure), (gst_value_serialize_structure), + (gst_value_deserialize_structure), (_gst_value_initialize): + * gst/gstvalue.h: + * tests/check/gst/gststructure.c: (GST_START_TEST), + (gst_structure_suite): + * tests/check/gst/gstvalue.c: (GST_START_TEST): + Added GstStructure to gst_value_table and its related functions. + Changed gst_structure_to_string to print ';' in the end. + Changed gst_caps_to_string to not print ';' beteween its + fields (structures) anymore and remove the lastes ';' from latest + structure. Now it is possible to have nested structures. + In addition, backward compatibilty is assured by accepting '\0' as + end delimiter. Fixes: #487969. + API: add gst_value_set_structure() + API: add gst_value_get_structure() + + 2007-10-19 Tim-Philipp Müller * gst/gstbus.c: diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 65cf1cd2c7..a090765a84 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -1797,14 +1797,20 @@ gst_caps_to_string (const GstCaps * caps) GstStructure *structure; char *sstr; - if (i > 0) - g_string_append (s, "; "); + if (i > 0) { + /* ';' is now added by gst_structure_to_string */ + g_string_append (s, " "); + } structure = gst_caps_get_structure (caps, i); sstr = gst_structure_to_string (structure); g_string_append (s, sstr); g_free (sstr); } + if (s->len && s->str[s->len - 1] == ';') { + /* remove latest ';' */ + s->str[--s->len] = '\0'; + } return g_string_free (s, FALSE); } @@ -1830,22 +1836,20 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string) } gst_caps_append_structure (caps, structure); - while (*s == ';') { - s++; + do { + while (g_ascii_isspace (*s)) s++; + if (*s == '\0') { + break; + } structure = gst_structure_from_string (s, &s); if (structure == NULL) { return FALSE; } gst_caps_append_structure (caps, structure); - while (g_ascii_isspace (*s)) - s++; - } - if (*s != 0) { - return FALSE; - } + } while (TRUE); return TRUE; } diff --git a/gst/gststructure.c b/gst/gststructure.c index 9dd1bb0093..0ed0785a3e 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -1421,6 +1421,8 @@ gst_structure_get_abbrs (gint * n_abbrs) {"str", G_TYPE_STRING} , {"s", G_TYPE_STRING} + , + {"structure", GST_TYPE_STRUCTURE} }; num = G_N_ELEMENTS (dyn_abbrs); /* permanently allocate and copy the array now */ @@ -1544,6 +1546,9 @@ gst_structure_to_string (const GstStructure * structure) gst_structure_to_abbr (type), GST_STR_NULL (t)); g_free (t); } + + g_string_append_c (s, ';'); + return g_string_free (s, FALSE); } @@ -1895,26 +1900,35 @@ gst_structure_from_string (const gchar * string, gchar ** end) copy = g_strdup (string); r = copy; + /* skipe spaces */ + while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' + && g_ascii_isspace (r[1])))) + r++; + name = r; if (!gst_structure_parse_string (r, &w, &r)) { GST_WARNING ("Failed to parse structure string"); goto error; } - /* skip spaces */ - while (g_ascii_isspace (*r) || (r[0] == '\\' && g_ascii_isspace (r[1]))) - r++; - if (*r != 0 && *r != ';' && *r != ',') { - GST_WARNING ("Failed to find delimiter, r=%s", r); - goto error; - } - save = *w; *w = 0; structure = gst_structure_empty_new (name); *w = save; - while (*r && (*r != ';')) { + do { + while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' + && g_ascii_isspace (r[1])))) + r++; + if (*r == ';') { + /* end of structure, get the next char and finish */ + r++; + break; + } + if (*r == '\0') { + /* accept \0 as end delimiter */ + break; + } if (*r != ',') { GST_WARNING ("Failed to find delimiter, r=%s", r); goto error; @@ -1928,10 +1942,8 @@ 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 (*r && (g_ascii_isspace (*r) || (r[0] == '\\' - && g_ascii_isspace (r[1])))) - r++; - } + + } while (TRUE); if (end) *end = (char *) string + (r - copy); diff --git a/gst/gstvalue.c b/gst/gstvalue.c index ea326de59b..130df3007f 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -1289,6 +1289,62 @@ gst_value_deserialize_caps (GValue * dest, const gchar * s) return FALSE; } +/**************** + * GstStructure * + ****************/ + +/** + * gst_value_set_structure: + * @value: a GValue initialized to GST_TYPE_STRUCTURE + * @structure: the structure to set the value to + * + * Sets the contents of @value to @structure. The actual + */ +void +gst_value_set_structure (GValue * value, const GstStructure * structure) +{ + g_return_if_fail (G_VALUE_TYPE (value) == GST_TYPE_STRUCTURE); + + g_value_set_boxed (value, structure); +} + +/** + * gst_value_get_structure: + * @value: a GValue initialized to GST_TYPE_STRUCTURE + * + * Gets the contents of @value. + * + * Returns: the contents of @value + */ +const GstStructure * +gst_value_get_structure (const GValue * value) +{ + g_return_val_if_fail (G_VALUE_TYPE (value) == GST_TYPE_STRUCTURE, NULL); + + return (GstStructure *) g_value_get_boxed (value); +} + +static char * +gst_value_serialize_structure (const GValue * value) +{ + GstStructure *structure = g_value_get_boxed (value); + + return gst_structure_to_string (structure); +} + +static gboolean +gst_value_deserialize_structure (GValue * dest, const gchar * s) +{ + GstStructure *structure; + + structure = gst_structure_from_string (s, NULL); + + if (structure) { + g_value_set_boxed (dest, structure); + return TRUE; + } + return FALSE; +} /************* * GstBuffer * @@ -4107,6 +4163,17 @@ _gst_value_initialize (void) gst_value.type = GST_TYPE_CAPS; gst_value_register (&gst_value); } + { + static GstValueTable gst_value = { + 0, + NULL, + gst_value_serialize_structure, + gst_value_deserialize_structure, + }; + + gst_value.type = GST_TYPE_STRUCTURE; + gst_value_register (&gst_value); + } { static GstValueTable gst_value = { 0, diff --git a/gst/gstvalue.h b/gst/gstvalue.h index d8242e25f8..e4107b2b4a 100644 --- a/gst/gstvalue.h +++ b/gst/gstvalue.h @@ -22,6 +22,7 @@ #include #include +#include G_BEGIN_DECLS @@ -140,6 +141,14 @@ G_BEGIN_DECLS */ #define GST_VALUE_HOLDS_CAPS(x) (G_VALUE_HOLDS(x, GST_TYPE_CAPS)) +/** + * GST_VALUE_HOLDS_STRUCTURE: + * @x: the #GValue to check + * + * Checks if the given #GValue contains a #GST_TYPE_STRUCTURE value. + */ +#define GST_VALUE_HOLDS_STRUCTURE(x) (G_VALUE_HOLDS(x, GST_TYPE_STRUCTURE)) + /** * GST_VALUE_HOLDS_BUFFER: * @x: the #GValue to check @@ -449,6 +458,12 @@ G_CONST_RETURN GstCaps * void gst_value_set_caps (GValue *value, const GstCaps *caps); +/* structure */ +G_CONST_RETURN GstStructure * + gst_value_get_structure (const GValue *value); +void gst_value_set_structure (GValue *value, + const GstStructure *structure); + /* fraction */ void gst_value_set_fraction (GValue *value, gint numerator, diff --git a/tests/check/gst/gststructure.c b/tests/check/gst/gststructure.c index de57f963f9..bba379d40f 100644 --- a/tests/check/gst/gststructure.c +++ b/tests/check/gst/gststructure.c @@ -294,6 +294,47 @@ GST_START_TEST (test_fixate_frac_list) GST_END_TEST; +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); + fail_unless (sc1 != NULL); + + sc2 = + gst_structure_new ("Image-Data", "Orientation", G_TYPE_STRING, "top-left", + 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_has_field_typed (sp, "Camera", + GST_TYPE_STRUCTURE)); + + str = gst_structure_to_string (sp); + fail_unless (str != NULL); + + 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;;")); + + g_free (str); + str = NULL; + + gst_structure_free (sc1); + gst_structure_free (sc2); + gst_structure_free (sp); + +} + +GST_END_TEST; + Suite * gst_structure_suite (void) { @@ -309,6 +350,7 @@ gst_structure_suite (void) tcase_add_test (tc_chain, test_structure_new); tcase_add_test (tc_chain, test_fixate); tcase_add_test (tc_chain, test_fixate_frac_list); + tcase_add_test (tc_chain, test_structure_nested); return s; } diff --git a/tests/check/gst/gstvalue.c b/tests/check/gst/gstvalue.c index fd60b217ca..6a0c0960c4 100644 --- a/tests/check/gst/gstvalue.c +++ b/tests/check/gst/gstvalue.c @@ -1495,7 +1495,7 @@ GST_START_TEST (test_date) s = NULL; fail_unless (g_str_equal (str, - "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22")); + "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22;")); s = gst_structure_from_string (str, NULL); g_free (str); @@ -1519,7 +1519,7 @@ GST_START_TEST (test_date) s = NULL; fail_unless (g_str_equal (str, - "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22")); + "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22;")); g_free (str); str = NULL; }