* @fieldname: the name of the field to set
* @...: variable arguments
*
- * Parses the variable arguments and sets fields accordingly.
+ * Parses the variable arguments and sets fields accordingly. Fields that
+ * weren't already part of the structure are added as needed.
* Variable arguments should be in the form field name, field type
* (as a GType), value(s). The last variable argument should be %NULL.
*/
GstStructureField field = { 0 };
field.name = fieldname;
-
type = va_arg (varargs, GType);
-#ifndef G_VALUE_COLLECT_INIT
- g_value_init (&field.value, type);
- G_VALUE_COLLECT (&field.value, varargs, 0, &err);
-#else
G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
-#endif
if (G_UNLIKELY (err)) {
g_critical ("%s", err);
return;
* @user_data: (closure): private data
*
* Calls the provided function once for each field in the #GstStructure. The
- * function must not modify the fields. Also see gst_structure_map_in_place().
+ * function must not modify the fields. Also see gst_structure_map_in_place()
+ * and gst_structure_filter_and_map_in_place().
*
* Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
* %FALSE otherwise.
}
/**
+ * gst_structure_filter_and_map_in_place:
+ * @structure: a #GstStructure
+ * @func: (scope call): a function to call for each field
+ * @user_data: (closure): private data
+ *
+ * Calls the provided function once for each field in the #GstStructure. In
+ * contrast to gst_structure_foreach(), the function may modify the fields.
+ * In contrast to gst_structure_map_in_place(), the field is removed from
+ * the structure if %FALSE is returned from the function.
+ * The structure must be mutable.
+ *
+ * Since: 1.6
+ */
+void
+gst_structure_filter_and_map_in_place (GstStructure * structure,
+ GstStructureFilterMapFunc func, gpointer user_data)
+{
+ guint i, len;
+ GstStructureField *field;
+ gboolean ret;
+
+ g_return_if_fail (structure != NULL);
+ g_return_if_fail (IS_MUTABLE (structure));
+ g_return_if_fail (func != NULL);
+ len = GST_STRUCTURE_FIELDS (structure)->len;
+
+ for (i = 0; i < len;) {
+ field = GST_STRUCTURE_FIELD (structure, i);
+
+ ret = func (field->name, &field->value, user_data);
+
+ if (!ret) {
+ if (G_IS_VALUE (&field->value)) {
+ g_value_unset (&field->value);
+ }
+ GST_STRUCTURE_FIELDS (structure) =
+ g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
+ len = GST_STRUCTURE_FIELDS (structure)->len;
+ } else {
+ i++;
+ }
+ }
+}
+
+/**
* gst_structure_id_has_field:
* @structure: a #GstStructure
* @field: #GQuark of the field name
return TRUE;
}
+/**
+ * gst_structure_get_flagset:
+ * @structure: a #GstStructure
+ * @fieldname: the name of a field
+ * @value_flags: (out) (allow-none): a pointer to a guint for the flags field
+ * @value_mask: (out) (allow-none): a pointer to a guint for the mask field
+ *
+ * Read the GstFlagSet flags and mask out of the structure into the
+ * provided pointers.
+ *
+ * Returns: %TRUE if the values could be set correctly. If there was no field
+ * with @fieldname or the existing field did not contain a GstFlagSet, this
+ * function returns %FALSE.
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_structure_get_flagset (const GstStructure * structure,
+ const gchar * fieldname, guint * value_flags, guint * value_mask)
+{
+ GstStructureField *field;
+
+ g_return_val_if_fail (structure != NULL, FALSE);
+ g_return_val_if_fail (fieldname != NULL, FALSE);
+
+ field = gst_structure_get_field (structure, fieldname);
+
+ if (field == NULL || !GST_VALUE_HOLDS_FLAG_SET (&field->value))
+ return FALSE;
+
+ if (value_flags)
+ *value_flags = gst_value_get_flagset_flags (&field->value);
+ if (value_mask)
+ *value_mask = gst_value_get_flagset_mask (&field->value);
+
+ return TRUE;
+}
+
typedef struct _GstStructureAbbreviation
{
const gchar *type_name;
{"sample", GST_TYPE_SAMPLE}
,
{"taglist", GST_TYPE_TAG_LIST}
+ ,
+ {"type", G_TYPE_GTYPE}
};
_num = G_N_ELEMENTS (dyn_abbrs);
/* permanently allocate and copy the array now */
int i;
GstStructureAbbreviation *abbrs;
gint n_abbrs;
+ GType ret;
g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
}
/* this is the fallback */
- return g_type_from_name (type_name);
+ ret = g_type_from_name (type_name);
+ /* If not found, try it as a dynamic type */
+ if (G_UNLIKELY (ret == 0))
+ ret = gst_dynamic_type_factory_load (type_name);
+ return ret;
}
static const char *
}
static GType
-gst_structure_value_get_generic_type (GValue * val)
+gst_structure_value_get_generic_type (const GValue * val)
{
if (G_VALUE_TYPE (val) == GST_TYPE_LIST
|| G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
g_string_append_len (s, "=(", 2);
g_string_append (s, gst_structure_to_abbr (type));
g_string_append_c (s, ')');
- g_string_append (s, t == NULL ? "NULL" : t);
- g_free (t);
+ if (t) {
+ g_string_append (s, t);
+ g_free (t);
+ } else {
+ GST_WARNING ("No value transform to serialize field '%s' of type '%s'",
+ g_quark_to_string (field->name), gst_structure_to_abbr (type));
+ g_string_append (s, "NULL");
+ }
}
g_string_append_c (s, ';');
return TRUE;
}
+gboolean
+priv__gst_structure_append_template_to_gstring (GQuark field_id,
+ const GValue * value, gpointer user_data)
+{
+ GType type = gst_structure_value_get_generic_type (value);
+ GString *s = (GString *) user_data;
+
+ g_string_append_len (s, ", ", 2);
+ /* FIXME: do we need to escape fieldnames? */
+ g_string_append (s, g_quark_to_string (field_id));
+ g_string_append_len (s, "=(", 2);
+ g_string_append (s, gst_structure_to_abbr (type));
+ g_string_append_c (s, ')');
+
+ //TODO(ensonic): table like GstStructureAbbreviation (or extend it)
+ if (type == G_TYPE_INT) {
+ g_string_append_len (s, "%i", 2);
+ } else if (type == G_TYPE_UINT) {
+ g_string_append_len (s, "%u", 2);
+ } else if (type == G_TYPE_FLOAT) {
+ g_string_append_len (s, "%f", 2);
+ } else if (type == G_TYPE_DOUBLE) {
+ g_string_append_len (s, "%lf", 3);
+ } else if (type == G_TYPE_STRING) {
+ g_string_append_len (s, "%s", 2);
+ } else if (type == G_TYPE_BOOLEAN) {
+ /* we normally store this as a string, but can parse it also from an int */
+ g_string_append_len (s, "%i", 2);
+ } else if (type == G_TYPE_INT64) {
+ g_string_append (s, "%" G_GINT64_FORMAT);
+ } else if (type == G_TYPE_UINT64) {
+ g_string_append (s, "%" G_GUINT64_FORMAT);
+ } else if (type == GST_TYPE_STRUCTURE) {
+ g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
+ } else if (g_type_is_a (type, G_TYPE_ENUM)
+ || g_type_is_a (type, G_TYPE_FLAGS)) {
+ g_string_append_len (s, "%i", 2);
+ } else if (type == G_TYPE_GTYPE) {
+ g_string_append_len (s, "%s", 2);
+ } else if (type == G_TYPE_POINTER) {
+ g_string_append_len (s, "%p", 2);
+ } else {
+ GST_WARNING ("unhandled type: %s", g_type_name (type));
+ g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
+ }
+
+ return TRUE;
+}
+
/**
* gst_structure_to_string:
* @structure: a #GstStructure
* Converts @structure to a human-readable string representation.
*
* For debugging purposes its easier to do something like this:
- * |[
+ * |[<!-- language="C" -->
* GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
* ]|
* This prints the structure in human readable form.
while (*s != '"') {
if (G_UNLIKELY (*s == 0))
return FALSE;
- if (G_UNLIKELY (*s == '\\'))
+ if (G_UNLIKELY (*s == '\\')) {
s++;
+ if (G_UNLIKELY (*s == 0))
+ return FALSE;
+ }
*w = *s;
w++;
s++;
while (*s != '"') {
if (G_UNLIKELY (*s == 0))
return FALSE;
- if (G_UNLIKELY (*s == '\\'))
+ if (G_UNLIKELY (*s == '\\')) {
s++;
+ if (G_UNLIKELY (*s == 0))
+ return FALSE;
+ }
s++;
}
s++;
s++;
ret = gst_structure_parse_value (s, &s, &value1, type);
- if (ret == FALSE)
+ if (!ret)
return FALSE;
while (g_ascii_isspace (*s))
s++;
ret = gst_structure_parse_value (s, &s, &value2, type);
- if (ret == FALSE)
+ if (!ret)
return FALSE;
while (g_ascii_isspace (*s))
s++;
ret = gst_structure_parse_value (s, &s, &value3, type);
- if (ret == FALSE)
+ if (!ret)
return FALSE;
while (g_ascii_isspace (*s))
}
ret = gst_structure_parse_value (s, &s, &list_value, type);
- if (ret == FALSE)
+ if (!ret)
return FALSE;
g_array_append_val (array, list_value);
memset (&list_value, 0, sizeof (list_value));
ret = gst_structure_parse_value (s, &s, &list_value, type);
- if (ret == FALSE)
+ if (!ret)
return FALSE;
g_array_append_val (array, list_value);
if (G_UNLIKELY (type == G_TYPE_INVALID)) {
GType try_types[] =
- { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
- G_TYPE_STRING
+ { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, GST_TYPE_FLAG_SET,
+ G_TYPE_BOOLEAN, G_TYPE_STRING
};
int i;