GstCaps *caps;
if (*s != '"') {
+ /* this can happen if caps are ANY, EMPTY, or only contains a single
+ * empty structure */
caps = gst_caps_from_string (s);
} else {
gchar *str = gst_string_unwrap (s);
};
int i;
- if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, TRUE)))
+ if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, FALSE)))
return FALSE;
/* Set NULL terminator for deserialization */
value_s = g_strndup (value_s, value_end - value_s);
} else {
g_value_init (value, type);
- if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s,
- (type != G_TYPE_STRING))))
+ if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, FALSE)))
return FALSE;
/* Set NULL terminator for deserialization */
value_s = g_strndup (value_s, value_end - value_s);
}
static gboolean
-gst_value_deserialize_segment (GValue * dest, const gchar * s)
+gst_value_deserialize_segment_internal (GValue * dest, const gchar * s,
+ gboolean unescape)
{
GstStructure *str;
GstSegment seg;
gboolean res;
+ gsize len;
+ gchar *t;
- str = gst_structure_from_string (s, NULL);
- if (str == NULL)
+ if (unescape) {
+ len = strlen (s);
+ if (G_UNLIKELY (*s != '"' || len < 2 || s[len - 1] != '"')) {
+ /* "\"" is not an accepted string, so len must be at least 2 */
+ GST_ERROR ("Failed deserializing segement: expected string to start and "
+ "end with '\"'");
+ return FALSE;
+ }
+ t = g_strdup (s + 1);
+ t[len - 2] = '\0';
+ /* removed trailing '"' */
+ str = gst_structure_from_string (t, NULL);
+ g_free (t);
+ } else {
+ str = gst_structure_from_string (s, NULL);
+ }
+ if (G_UNLIKELY (str == NULL))
return FALSE;
res = gst_structure_id_get (str,
return res;
}
+static gboolean
+gst_value_deserialize_segment (GValue * dest, const gchar * s)
+{
+ return gst_value_deserialize_segment_internal (dest, s, TRUE);
+}
+
/****************
* GstStructure *
****************/
GstStructure *structure = g_value_get_boxed (value);
return priv_gst_string_take_and_wrap (gst_structure_to_string (structure));
+ /* string should always end up being wrapped, since a structure string
+ * ends in a ';' character */
}
static gboolean
GstStructure *structure;
if (*s != '"') {
+ /* the output of gst_value_serialize_structure would never produce
+ * such a string, but a user may pass to gst_structure_from_string
+ * the string:
+ * name, sub=(GstStructure)sub-name, val=(int)5;
+ * and expect sub to be read as an *empty* structure with the name
+ * sub-name. Similar to
+ * name, caps=(GstCaps)video/x-raw, val=(int)5;
+ * which gst_structure_to_string can produce. */
structure = gst_structure_from_string (s, NULL);
} else {
gchar *str = gst_string_unwrap (s);
GstCapsFeatures *features;
if (*s != '"') {
+ /* This can happen if gst_caps_features_to_string only returns
+ * ALL, NONE, or a single features name, which means it is not
+ * actually wrapped by priv_gst_string_take_and_wrap */
features = gst_caps_features_from_string (s);
} else {
gchar *str = gst_string_unwrap (s);
GstTagList *taglist;
if (*s != '"') {
+ /* the output of gst_value_serialize_tag_list would never produce
+ * such a string, but a user may pass to gst_structure_from_string
+ * the string:
+ * name, list=(GstTagList)taglist, val=(int)5;
+ * and expect list to be read as an *empty* tag list. Similar to
+ * name, caps=(GstCaps)video/x-raw, val=(int)5;
+ * which gst_structure_to_string can produce. */
taglist = gst_tag_list_new_from_string (s);
} else {
gchar *str = gst_string_unwrap (s);
GstTagList *taglist = g_value_get_boxed (value);
return priv_gst_string_take_and_wrap (gst_tag_list_to_string (taglist));
+ /* string should always end up being wrapped, since a taglist (structure)
+ * string ends in a ';' character */
}
g_strdelimit (fields[2], "_", '=');
g_base64_decode_inplace (fields[2], &outlen);
GST_TRACE ("segment : %s", fields[2]);
- if (!gst_value_deserialize_segment (&sval, fields[2]))
+ if (!gst_value_deserialize_segment_internal (&sval, fields[2], FALSE))
goto fail;
}
const gchar *op;
gint ret;
GType str_type;
- const gchar *str_result;
} comparisons[] = {
/* *INDENT-OFF* */
- {"foo,bar=(int)1", "foo,bar=(int)1", "compare", GST_VALUE_EQUAL, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)1", "is_subset", TRUE, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
- {"foo,bar=(int)1", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
- {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0, NULL},
- {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "is_subset", FALSE, 0, NULL},
- {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
- {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
- {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "compare", GST_VALUE_UNORDERED, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "is_subset", TRUE, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
- {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
- {"foo,bar=(int)1", "foo,bar=(int)2", "compare", GST_VALUE_UNORDERED, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)2", "is_subset", FALSE, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)2", "intersect", FALSE, 0, NULL},
- {"foo,bar=(int)1", "foo,bar=(int)2", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
- {"foo,bar=(int)1", "baz,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0, NULL},
- {"foo,bar=(int)1", "baz,bar=(int)1", "is_subset", FALSE, 0, NULL},
- {"foo,bar=(int)1", "baz,bar=(int)1", "intersect", FALSE, 0, NULL},
+ {"foo,bar=(int)1", "foo,bar=(int)1", "compare", GST_VALUE_EQUAL, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)1", "is_subset", TRUE, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)1", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0},
+ {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "is_subset", FALSE, 0},
+ {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "compare", GST_VALUE_UNORDERED, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "is_subset", TRUE, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "intersect", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "union", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)1", "foo,bar=(int)2", "compare", GST_VALUE_UNORDERED, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)2", "is_subset", FALSE, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)2", "intersect", FALSE, 0},
+ {"foo,bar=(int)1", "foo,bar=(int)2", "union", TRUE, GST_TYPE_STRUCTURE},
+ {"foo,bar=(int)1", "baz,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0},
+ {"foo,bar=(int)1", "baz,bar=(int)1", "is_subset", FALSE, 0},
+ {"foo,bar=(int)1", "baz,bar=(int)1", "intersect", FALSE, 0},
#if 0
/* deserializing lists is not implemented (but this should still work!) */
- {"foo,bar=(int)1", "baz,bar=(int)1", "union", TRUE, G_TYPE_LIST, "{foo,bar=(int)1;, baz,bar=(int)1;}"},
+ {"foo,bar=(int)1", "baz,bar=(int)1", "union", TRUE, G_TYPE_LIST},
#endif
/* *INDENT-ON* */
};
fail_unless (s2 != NULL);
GST_DEBUG ("checking %s with structure1 %" GST_PTR_FORMAT " structure2 %"
- GST_PTR_FORMAT " is %d, %s", comparisons[i].op, s1, s2,
- comparisons[i].ret, comparisons[i].str_result);
+ GST_PTR_FORMAT " is %d", comparisons[i].op, s1, s2, comparisons[i].ret);
g_value_init (&v1, GST_TYPE_STRUCTURE);
gst_value_set_structure (&v1, s1);
str = gst_value_serialize (&v3);
GST_LOG ("result %s", str);
- g_free (str);
g_value_init (&result, comparisons[i].str_type);
- fail_unless (gst_value_deserialize (&result,
- comparisons[i].str_result));
+ fail_unless (gst_value_deserialize (&result, str));
+ g_free (str);
fail_unless (gst_value_compare (&result, &v3) == GST_VALUE_EQUAL);
g_value_unset (&v3);
g_value_unset (&result);