Merge remote-tracking branch 'origin/master' into 0.11
[platform/upstream/gstreamer.git] / gst / gststructure.c
1 /* GStreamer
2  * Copyright (C) 2003 David A. Schleef <ds@schleef.org>
3  *
4  * gststructure.c: lists of { GQuark, GValue } tuples
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:gststructure
24  * @short_description: Generic structure containing fields of names and values
25  * @see_also: #GstCaps, #GstMessage, #GstEvent, #GstQuery
26  *
27  * A #GstStructure is a collection of key/value pairs. The keys are expressed
28  * as GQuarks and the values can be of any GType.
29  *
30  * In addition to the key/value pairs, a #GstStructure also has a name. The name
31  * starts with a letter and can be folled by letters, numbers and any of "/-_.:".
32  *
33  * #GstStructure is used by various GStreamer subsystems to store information
34  * in a flexible and extensible way. A #GstStructure does not have a refcount
35  * because it usually is part of a higher level object such as #GstCaps. It
36  * provides a means to enforce mutability using the refcount of the parent
37  * with the gst_structure_set_parent_refcount() method.
38  *
39  * A #GstStructure can be created with gst_structure_new_empty() or
40  * gst_structure_new(), which both take a name and an optional set of
41  * key/value pairs along with the types of the values.
42  *
43  * Field values can be changed with gst_structure_set_value() or
44  * gst_structure_set().
45  *
46  * Field values can be retrieved with gst_structure_get_value() or the more
47  * convenient gst_structure_get_*() functions.
48  *
49  * Fields can be removed with gst_structure_remove_field() or
50  * gst_structure_remove_fields().
51  *
52  * Strings in structures must be ASCII or UTF-8 encoded. Other encodings are
53  * not allowed. Strings must not be empty either, but may be NULL.
54  *
55  * Last reviewed on 2009-06-08 (0.10.23)
56  */
57
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61
62 #include <string.h>
63
64 #include "gst_private.h"
65 #include "gstquark.h"
66 #include <gst/gst.h>
67 #include <gobject/gvaluecollector.h>
68
69 typedef struct _GstStructureField GstStructureField;
70
71 struct _GstStructureField
72 {
73   GQuark name;
74   GValue value;
75 };
76
77 typedef struct
78 {
79   GstStructure s;
80
81   /* owned by parent structure, NULL if no parent */
82   gint *parent_refcount;
83
84   GArray *fields;
85 } GstStructureImpl;
86
87 #define GST_STRUCTURE_REFCOUNT(s) (((GstStructureImpl*)(s))->parent_refcount)
88 #define GST_STRUCTURE_FIELDS(s) (((GstStructureImpl*)(s))->fields)
89
90 #define GST_STRUCTURE_FIELD(structure, index) \
91     &g_array_index(GST_STRUCTURE_FIELDS(structure), GstStructureField, (index))
92
93 #define IS_MUTABLE(structure) \
94     (!GST_STRUCTURE_REFCOUNT(structure) || \
95      g_atomic_int_get (GST_STRUCTURE_REFCOUNT(structure)) == 1)
96
97 #define IS_TAGLIST(structure) \
98     (structure->name == GST_QUARK (TAGLIST))
99
100 static void gst_structure_set_field (GstStructure * structure,
101     GstStructureField * field);
102 static GstStructureField *gst_structure_get_field (const GstStructure *
103     structure, const gchar * fieldname);
104 static GstStructureField *gst_structure_id_get_field (const GstStructure *
105     structure, GQuark field);
106 static void gst_structure_transform_to_string (const GValue * src_value,
107     GValue * dest_value);
108 static GstStructure *gst_structure_copy_conditional (const GstStructure *
109     structure);
110 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
111     GValue * value, GType default_type);
112 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
113
114 GType _gst_structure_type = 0;
115
116
117 G_DEFINE_BOXED_TYPE (GstStructure, gst_structure,
118     gst_structure_copy_conditional, gst_structure_free);
119
120 void
121 _priv_gst_structure_initialize (void)
122 {
123   _gst_structure_type = gst_structure_get_type ();
124
125   g_value_register_transform_func (_gst_structure_type, G_TYPE_STRING,
126       gst_structure_transform_to_string);
127 }
128
129 static GstStructure *
130 gst_structure_new_id_empty_with_size (GQuark quark, guint prealloc)
131 {
132   GstStructureImpl *structure;
133
134   structure = g_slice_new (GstStructureImpl);
135   ((GstStructure *) structure)->type = _gst_structure_type;
136   ((GstStructure *) structure)->name = quark;
137   GST_STRUCTURE_REFCOUNT (structure) = NULL;
138   GST_STRUCTURE_FIELDS (structure) =
139       g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc);
140
141   return GST_STRUCTURE_CAST (structure);
142 }
143
144 /**
145  * gst_structure_new_id_empty:
146  * @quark: name of new structure
147  *
148  * Creates a new, empty #GstStructure with the given name as a GQuark.
149  *
150  * Free-function: gst_structure_free
151  *
152  * Returns: (transfer full): a new, empty #GstStructure
153  */
154 GstStructure *
155 gst_structure_new_id_empty (GQuark quark)
156 {
157   g_return_val_if_fail (quark != 0, NULL);
158
159   return gst_structure_new_id_empty_with_size (quark, 0);
160 }
161
162 #ifndef G_DISABLE_CHECKS
163 static gboolean
164 gst_structure_validate_name (const gchar * name)
165 {
166   const gchar *s;
167
168   g_return_val_if_fail (name != NULL, FALSE);
169
170   if (G_UNLIKELY (!g_ascii_isalpha (*name))) {
171     GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s",
172         *name, name);
173     return FALSE;
174   }
175
176   /* FIXME: test name string more */
177   s = &name[1];
178   while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+", *s) != NULL))
179     s++;
180   if (G_UNLIKELY (*s != '\0')) {
181     GST_WARNING ("Invalid character '%c' at offset %" G_GUINTPTR_FORMAT " in"
182         " structure name: %s", *s, ((guintptr) s - (guintptr) name), name);
183     return FALSE;
184   }
185
186   return TRUE;
187 }
188 #endif
189
190 /**
191  * gst_structure_new_empty:
192  * @name: name of new structure
193  *
194  * Creates a new, empty #GstStructure with the given @name.
195  *
196  * See gst_structure_set_name() for constraints on the @name parameter.
197  *
198  * Free-function: gst_structure_free
199  *
200  * Returns: (transfer full): a new, empty #GstStructure
201  */
202 GstStructure *
203 gst_structure_new_empty (const gchar * name)
204 {
205   g_return_val_if_fail (gst_structure_validate_name (name), NULL);
206
207   return gst_structure_new_id_empty_with_size (g_quark_from_string (name), 0);
208 }
209
210 /**
211  * gst_structure_new:
212  * @name: name of new structure
213  * @firstfield: name of first field to set
214  * @...: additional arguments
215  *
216  * Creates a new #GstStructure with the given name.  Parses the
217  * list of variable arguments and sets fields to the values listed.
218  * Variable arguments should be passed as field name, field type,
219  * and value.  Last variable argument should be NULL.
220  *
221  * Free-function: gst_structure_free
222  *
223  * Returns: (transfer full): a new #GstStructure
224  */
225 GstStructure *
226 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
227 {
228   GstStructure *structure;
229   va_list varargs;
230
231   va_start (varargs, firstfield);
232   structure = gst_structure_new_valist (name, firstfield, varargs);
233   va_end (varargs);
234
235   return structure;
236 }
237
238 /**
239  * gst_structure_new_valist:
240  * @name: name of new structure
241  * @firstfield: name of first field to set
242  * @varargs: variable argument list
243  *
244  * Creates a new #GstStructure with the given @name.  Structure fields
245  * are set according to the varargs in a manner similar to
246  * gst_structure_new().
247  *
248  * See gst_structure_set_name() for constraints on the @name parameter.
249  *
250  * Free-function: gst_structure_free
251  *
252  * Returns: (transfer full): a new #GstStructure
253  */
254 GstStructure *
255 gst_structure_new_valist (const gchar * name,
256     const gchar * firstfield, va_list varargs)
257 {
258   GstStructure *structure;
259
260   structure = gst_structure_new_empty (name);
261
262   if (structure)
263     gst_structure_set_valist (structure, firstfield, varargs);
264
265   return structure;
266 }
267
268 /**
269  * gst_structure_set_parent_refcount:
270  * @structure: a #GstStructure
271  * @refcount: (in): a pointer to the parent's refcount
272  *
273  * Sets the parent_refcount field of #GstStructure. This field is used to
274  * determine whether a structure is mutable or not. This function should only be
275  * called by code implementing parent objects of #GstStructure, as described in
276  * the MT Refcounting section of the design documents.
277  *
278  * Returns: %TRUE if the parent refcount could be set.
279  */
280 gboolean
281 gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount)
282 {
283   g_return_val_if_fail (structure != NULL, FALSE);
284
285   /* if we have a parent_refcount already, we can only clear
286    * if with a NULL refcount */
287   if (GST_STRUCTURE_REFCOUNT (structure)) {
288     if (refcount != NULL) {
289       g_return_val_if_fail (refcount == NULL, FALSE);
290       return FALSE;
291     }
292   } else {
293     if (refcount == NULL) {
294       g_return_val_if_fail (refcount != NULL, FALSE);
295       return FALSE;
296     }
297   }
298
299   GST_STRUCTURE_REFCOUNT (structure) = refcount;
300
301   return TRUE;
302 }
303
304 /**
305  * gst_structure_copy:
306  * @structure: a #GstStructure to duplicate
307  *
308  * Duplicates a #GstStructure and all its fields and values.
309  *
310  * Free-function: gst_structure_free
311  *
312  * Returns: (transfer none): a new #GstStructure.
313  */
314 GstStructure *
315 gst_structure_copy (const GstStructure * structure)
316 {
317   GstStructure *new_structure;
318   GstStructureField *field;
319   guint i, len;
320
321   g_return_val_if_fail (structure != NULL, NULL);
322
323   len = GST_STRUCTURE_FIELDS (structure)->len;
324   new_structure = gst_structure_new_id_empty_with_size (structure->name, len);
325
326   for (i = 0; i < len; i++) {
327     GstStructureField new_field = { 0 };
328
329     field = GST_STRUCTURE_FIELD (structure, i);
330
331     new_field.name = field->name;
332     gst_value_init_and_copy (&new_field.value, &field->value);
333     g_array_append_val (GST_STRUCTURE_FIELDS (new_structure), new_field);
334   }
335
336   return new_structure;
337 }
338
339 /**
340  * gst_structure_free:
341  * @structure: (in) (transfer full): the #GstStructure to free
342  *
343  * Frees a #GstStructure and all its fields and values. The structure must not
344  * have a parent when this function is called.
345  */
346 void
347 gst_structure_free (GstStructure * structure)
348 {
349   GstStructureField *field;
350   guint i, len;
351
352   g_return_if_fail (structure != NULL);
353   g_return_if_fail (GST_STRUCTURE_REFCOUNT (structure) == NULL);
354
355   len = GST_STRUCTURE_FIELDS (structure)->len;
356   for (i = 0; i < len; i++) {
357     field = GST_STRUCTURE_FIELD (structure, i);
358
359     if (G_IS_VALUE (&field->value)) {
360       g_value_unset (&field->value);
361     }
362   }
363   g_array_free (GST_STRUCTURE_FIELDS (structure), TRUE);
364 #ifdef USE_POISONING
365   memset (structure, 0xff, sizeof (GstStructure));
366 #endif
367   g_slice_free1 (sizeof (GstStructureImpl), structure);
368 }
369
370 /**
371  * gst_structure_get_name:
372  * @structure: a #GstStructure
373  *
374  * Get the name of @structure as a string.
375  *
376  * Returns: the name of the structure.
377  */
378 const gchar *
379 gst_structure_get_name (const GstStructure * structure)
380 {
381   g_return_val_if_fail (structure != NULL, NULL);
382
383   return g_quark_to_string (structure->name);
384 }
385
386 /**
387  * gst_structure_has_name:
388  * @structure: a #GstStructure
389  * @name: structure name to check for
390  *
391  * Checks if the structure has the given name
392  *
393  * Returns: TRUE if @name matches the name of the structure.
394  */
395 gboolean
396 gst_structure_has_name (const GstStructure * structure, const gchar * name)
397 {
398   const gchar *structure_name;
399
400   g_return_val_if_fail (structure != NULL, FALSE);
401   g_return_val_if_fail (name != NULL, FALSE);
402
403   /* getting the string is cheap and comparing short strings is too
404    * should be faster than getting the quark for name and comparing the quarks
405    */
406   structure_name = g_quark_to_string (structure->name);
407
408   return (structure_name && strcmp (structure_name, name) == 0);
409 }
410
411 /**
412  * gst_structure_get_name_id:
413  * @structure: a #GstStructure
414  *
415  * Get the name of @structure as a GQuark.
416  *
417  * Returns: the quark representing the name of the structure.
418  */
419 GQuark
420 gst_structure_get_name_id (const GstStructure * structure)
421 {
422   g_return_val_if_fail (structure != NULL, 0);
423
424   return structure->name;
425 }
426
427 /**
428  * gst_structure_set_name:
429  * @structure: a #GstStructure
430  * @name: the new name of the structure
431  *
432  * Sets the name of the structure to the given @name.  The string
433  * provided is copied before being used. It must not be empty, start with a
434  * letter and can be followed by letters, numbers and any of "/-_.:".
435  */
436 void
437 gst_structure_set_name (GstStructure * structure, const gchar * name)
438 {
439   g_return_if_fail (structure != NULL);
440   g_return_if_fail (IS_MUTABLE (structure));
441   g_return_if_fail (gst_structure_validate_name (name));
442
443   structure->name = g_quark_from_string (name);
444 }
445
446 static inline void
447 gst_structure_id_set_value_internal (GstStructure * structure, GQuark field,
448     const GValue * value)
449 {
450   GstStructureField gsfield = { 0, {0,} };
451
452   gsfield.name = field;
453   gst_value_init_and_copy (&gsfield.value, value);
454
455   gst_structure_set_field (structure, &gsfield);
456 }
457
458 /**
459  * gst_structure_id_set_value:
460  * @structure: a #GstStructure
461  * @field: a #GQuark representing a field
462  * @value: the new value of the field
463  *
464  * Sets the field with the given GQuark @field to @value.  If the field
465  * does not exist, it is created.  If the field exists, the previous
466  * value is replaced and freed.
467  */
468 void
469 gst_structure_id_set_value (GstStructure * structure,
470     GQuark field, const GValue * value)
471 {
472
473   g_return_if_fail (structure != NULL);
474   g_return_if_fail (G_IS_VALUE (value));
475   g_return_if_fail (IS_MUTABLE (structure));
476
477   gst_structure_id_set_value_internal (structure, field, value);
478 }
479
480 /**
481  * gst_structure_set_value:
482  * @structure: a #GstStructure
483  * @fieldname: the name of the field to set
484  * @value: the new value of the field
485  *
486  * Sets the field with the given name @field to @value.  If the field
487  * does not exist, it is created.  If the field exists, the previous
488  * value is replaced and freed.
489  */
490 void
491 gst_structure_set_value (GstStructure * structure,
492     const gchar * fieldname, const GValue * value)
493 {
494   g_return_if_fail (structure != NULL);
495   g_return_if_fail (fieldname != NULL);
496   g_return_if_fail (G_IS_VALUE (value));
497   g_return_if_fail (IS_MUTABLE (structure));
498
499   gst_structure_id_set_value_internal (structure,
500       g_quark_from_string (fieldname), value);
501 }
502
503 static inline void
504 gst_structure_id_take_value_internal (GstStructure * structure, GQuark field,
505     GValue * value)
506 {
507   GstStructureField gsfield = { 0, {0,} };
508
509   gsfield.name = field;
510   gsfield.value = *value;
511
512   gst_structure_set_field (structure, &gsfield);
513
514   /* we took ownership */
515 #ifdef USE_POISONING
516   memset (value, 0, sizeof (GValue));
517 #else
518   value->g_type = G_TYPE_INVALID;
519 #endif
520 }
521
522 /**
523  * gst_structure_id_take_value:
524  * @structure: a #GstStructure
525  * @field: a #GQuark representing a field
526  * @value: (transfer full): the new value of the field
527  *
528  * Sets the field with the given GQuark @field to @value.  If the field
529  * does not exist, it is created.  If the field exists, the previous
530  * value is replaced and freed.
531  *
532  * Since: 0.10.31
533  */
534 void
535 gst_structure_id_take_value (GstStructure * structure, GQuark field,
536     GValue * value)
537 {
538   g_return_if_fail (structure != NULL);
539   g_return_if_fail (G_IS_VALUE (value));
540   g_return_if_fail (IS_MUTABLE (structure));
541
542   gst_structure_id_take_value_internal (structure, field, value);
543 }
544
545 /**
546  * gst_structure_take_value:
547  * @structure: a #GstStructure
548  * @fieldname: the name of the field to set
549  * @value: (transfer full): the new value of the field
550  *
551  * Sets the field with the given name @field to @value.  If the field
552  * does not exist, it is created.  If the field exists, the previous
553  * value is replaced and freed. The function will take ownership of @value.
554  *
555  * Since: 0.10.31
556  */
557 void
558 gst_structure_take_value (GstStructure * structure, const gchar * fieldname,
559     GValue * value)
560 {
561   g_return_if_fail (structure != NULL);
562   g_return_if_fail (fieldname != NULL);
563   g_return_if_fail (G_IS_VALUE (value));
564   g_return_if_fail (IS_MUTABLE (structure));
565
566   gst_structure_id_take_value_internal (structure,
567       g_quark_from_string (fieldname), value);
568 }
569
570 static void
571 gst_structure_set_valist_internal (GstStructure * structure,
572     const gchar * fieldname, va_list varargs)
573 {
574   gchar *err = NULL;
575   GType type;
576
577   while (fieldname) {
578     GstStructureField field = { 0 };
579
580     field.name = g_quark_from_string (fieldname);
581
582     type = va_arg (varargs, GType);
583
584     G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
585     if (G_UNLIKELY (err)) {
586       g_critical ("%s", err);
587       return;
588     }
589     gst_structure_set_field (structure, &field);
590
591     fieldname = va_arg (varargs, gchar *);
592   }
593 }
594
595 /**
596  * gst_structure_set:
597  * @structure: a #GstStructure
598  * @fieldname: the name of the field to set
599  * @...: variable arguments
600  *
601  * Parses the variable arguments and sets fields accordingly.
602  * Variable arguments should be in the form field name, field type
603  * (as a GType), value(s).  The last variable argument should be NULL.
604  */
605 void
606 gst_structure_set (GstStructure * structure, const gchar * field, ...)
607 {
608   va_list varargs;
609
610   g_return_if_fail (structure != NULL);
611   g_return_if_fail (IS_MUTABLE (structure) || field == NULL);
612
613   va_start (varargs, field);
614   gst_structure_set_valist_internal (structure, field, varargs);
615   va_end (varargs);
616 }
617
618 /**
619  * gst_structure_set_valist:
620  * @structure: a #GstStructure
621  * @fieldname: the name of the field to set
622  * @varargs: variable arguments
623  *
624  * va_list form of gst_structure_set().
625  */
626 void
627 gst_structure_set_valist (GstStructure * structure,
628     const gchar * fieldname, va_list varargs)
629 {
630   g_return_if_fail (structure != NULL);
631   g_return_if_fail (IS_MUTABLE (structure));
632
633   gst_structure_set_valist_internal (structure, fieldname, varargs);
634 }
635
636 static void
637 gst_structure_id_set_valist_internal (GstStructure * structure,
638     GQuark fieldname, va_list varargs)
639 {
640   gchar *err = NULL;
641   GType type;
642
643   while (fieldname) {
644     GstStructureField field = { 0 };
645
646     field.name = fieldname;
647
648     type = va_arg (varargs, GType);
649
650 #ifndef G_VALUE_COLLECT_INIT
651     g_value_init (&field.value, type);
652     G_VALUE_COLLECT (&field.value, varargs, 0, &err);
653 #else
654     G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
655 #endif
656     if (G_UNLIKELY (err)) {
657       g_critical ("%s", err);
658       return;
659     }
660     gst_structure_set_field (structure, &field);
661
662     fieldname = va_arg (varargs, GQuark);
663   }
664 }
665
666 /**
667  * gst_structure_id_set:
668  * @structure: a #GstStructure
669  * @fieldname: the GQuark for the name of the field to set
670  * @...: variable arguments
671  *
672  * Identical to gst_structure_set, except that field names are
673  * passed using the GQuark for the field name. This allows more efficient
674  * setting of the structure if the caller already knows the associated
675  * quark values.
676  * The last variable argument must be NULL.
677  *
678  * Since: 0.10.10
679  */
680 void
681 gst_structure_id_set (GstStructure * structure, GQuark field, ...)
682 {
683   va_list varargs;
684
685   g_return_if_fail (structure != NULL);
686
687   va_start (varargs, field);
688   gst_structure_id_set_valist_internal (structure, field, varargs);
689   va_end (varargs);
690 }
691
692 /**
693  * gst_structure_id_set_valist:
694  * @structure: a #GstStructure
695  * @fieldname: the name of the field to set
696  * @varargs: variable arguments
697  *
698  * va_list form of gst_structure_id_set().
699  *
700  * Since: 0.10.10
701  */
702 void
703 gst_structure_id_set_valist (GstStructure * structure,
704     GQuark fieldname, va_list varargs)
705 {
706   g_return_if_fail (structure != NULL);
707   g_return_if_fail (IS_MUTABLE (structure));
708
709   gst_structure_id_set_valist_internal (structure, fieldname, varargs);
710 }
711
712 /**
713  * gst_structure_new_id:
714  * @name_quark: name of new structure
715  * @field_quark: the GQuark for the name of the field to set
716  * @...: variable arguments
717  *
718  * Creates a new #GstStructure with the given name as a GQuark, followed by
719  * fieldname quark, GType, argument(s) "triplets" in the same format as
720  * gst_structure_id_set(). Basically a convenience wrapper around
721  * gst_structure_new_id_empty() and gst_structure_id_set().
722  *
723  * The last variable argument must be NULL (or 0).
724  *
725  * Free-function: gst_structure_free
726  *
727  * Returns: (transfer full): a new #GstStructure
728  *
729  * Since: 0.10.24
730  */
731 GstStructure *
732 gst_structure_new_id (GQuark name_quark, GQuark field_quark, ...)
733 {
734   GstStructure *s;
735   va_list varargs;
736
737   g_return_val_if_fail (name_quark != 0, NULL);
738   g_return_val_if_fail (field_quark != 0, NULL);
739
740   s = gst_structure_new_id_empty (name_quark);
741
742   va_start (varargs, field_quark);
743   gst_structure_id_set_valist_internal (s, field_quark, varargs);
744   va_end (varargs);
745
746   return s;
747 }
748
749 #if GST_VERSION_NANO == 1
750 #define GIT_G_WARNING g_warning
751 #else
752 #define GIT_G_WARNING GST_WARNING
753 #endif
754
755 /* If the structure currently contains a field with the same name, it is
756  * replaced with the provided field. Otherwise, the field is added to the
757  * structure. The field's value is not deeply copied.
758  */
759 static void
760 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
761 {
762   GstStructureField *f;
763   guint i, len = GST_STRUCTURE_FIELDS (structure)->len;
764
765   if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) {
766     const gchar *s;
767
768     s = g_value_get_string (&field->value);
769     /* only check for NULL strings in taglists, as they are allowed in message
770      * structs, e.g. error message debug strings */
771     if (G_UNLIKELY (IS_TAGLIST (structure) && (s == NULL || *s == '\0'))) {
772       if (s == NULL) {
773         GIT_G_WARNING ("Trying to set NULL string on field '%s' on taglist. "
774             "Please file a bug.", g_quark_to_string (field->name));
775         g_value_unset (&field->value);
776         return;
777       } else {
778         /* empty strings never make sense */
779         GIT_G_WARNING ("Trying to set empty string on taglist field '%s'. "
780             "Please file a bug.", g_quark_to_string (field->name));
781         g_value_unset (&field->value);
782         return;
783       }
784     } else if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) {
785       g_warning ("Trying to set string on %s field '%s', but string is not "
786           "valid UTF-8. Please file a bug.",
787           IS_TAGLIST (structure) ? "taglist" : "structure",
788           g_quark_to_string (field->name));
789       g_value_unset (&field->value);
790       return;
791     }
792   } else if (G_UNLIKELY (G_VALUE_HOLDS (&field->value, G_TYPE_DATE))) {
793     const GDate *d;
794
795     d = g_value_get_boxed (&field->value);
796     /* only check for NULL GDates in taglists, as they might make sense
797      * in other, generic structs */
798     if (G_UNLIKELY ((IS_TAGLIST (structure) && d == NULL))) {
799       GIT_G_WARNING ("Trying to set NULL GDate on field '%s' on taglist. "
800           "Please file a bug.", g_quark_to_string (field->name));
801       g_value_unset (&field->value);
802       return;
803     } else if (G_UNLIKELY (d != NULL && !g_date_valid (d))) {
804       g_warning
805           ("Trying to set invalid GDate on %s field '%s'. Please file a bug.",
806           IS_TAGLIST (structure) ? "taglist" : "structure",
807           g_quark_to_string (field->name));
808       g_value_unset (&field->value);
809       return;
810     }
811   }
812
813   for (i = 0; i < len; i++) {
814     f = GST_STRUCTURE_FIELD (structure, i);
815
816     if (G_UNLIKELY (f->name == field->name)) {
817       g_value_unset (&f->value);
818       memcpy (f, field, sizeof (GstStructureField));
819       return;
820     }
821   }
822
823   g_array_append_val (GST_STRUCTURE_FIELDS (structure), *field);
824 }
825
826 /* If there is no field with the given ID, NULL is returned.
827  */
828 static GstStructureField *
829 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
830 {
831   GstStructureField *field;
832   guint i, len;
833
834   len = GST_STRUCTURE_FIELDS (structure)->len;
835
836   for (i = 0; i < len; i++) {
837     field = GST_STRUCTURE_FIELD (structure, i);
838
839     if (G_UNLIKELY (field->name == field_id))
840       return field;
841   }
842
843   return NULL;
844 }
845
846 /* If there is no field with the given ID, NULL is returned.
847  */
848 static GstStructureField *
849 gst_structure_get_field (const GstStructure * structure,
850     const gchar * fieldname)
851 {
852   g_return_val_if_fail (structure != NULL, NULL);
853   g_return_val_if_fail (fieldname != NULL, NULL);
854
855   return gst_structure_id_get_field (structure,
856       g_quark_from_string (fieldname));
857 }
858
859 /**
860  * gst_structure_get_value:
861  * @structure: a #GstStructure
862  * @fieldname: the name of the field to get
863  *
864  * Get the value of the field with name @fieldname.
865  *
866  * Returns: the #GValue corresponding to the field with the given name.
867  */
868 const GValue *
869 gst_structure_get_value (const GstStructure * structure,
870     const gchar * fieldname)
871 {
872   GstStructureField *field;
873
874   g_return_val_if_fail (structure != NULL, NULL);
875   g_return_val_if_fail (fieldname != NULL, NULL);
876
877   field = gst_structure_get_field (structure, fieldname);
878   if (field == NULL)
879     return NULL;
880
881   return &field->value;
882 }
883
884 /**
885  * gst_structure_id_get_value:
886  * @structure: a #GstStructure
887  * @field: the #GQuark of the field to get
888  *
889  * Get the value of the field with GQuark @field.
890  *
891  * Returns: the #GValue corresponding to the field with the given name
892  *          identifier.
893  */
894 const GValue *
895 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
896 {
897   GstStructureField *gsfield;
898
899   g_return_val_if_fail (structure != NULL, NULL);
900
901   gsfield = gst_structure_id_get_field (structure, field);
902   if (gsfield == NULL)
903     return NULL;
904
905   return &gsfield->value;
906 }
907
908 /**
909  * gst_structure_remove_field:
910  * @structure: a #GstStructure
911  * @fieldname: the name of the field to remove
912  *
913  * Removes the field with the given name.  If the field with the given
914  * name does not exist, the structure is unchanged.
915  */
916 void
917 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
918 {
919   GstStructureField *field;
920   GQuark id;
921   guint i, len;
922
923   g_return_if_fail (structure != NULL);
924   g_return_if_fail (fieldname != NULL);
925   g_return_if_fail (IS_MUTABLE (structure));
926
927   id = g_quark_from_string (fieldname);
928   len = GST_STRUCTURE_FIELDS (structure)->len;
929
930   for (i = 0; i < len; i++) {
931     field = GST_STRUCTURE_FIELD (structure, i);
932
933     if (field->name == id) {
934       if (G_IS_VALUE (&field->value)) {
935         g_value_unset (&field->value);
936       }
937       GST_STRUCTURE_FIELDS (structure) =
938           g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
939       return;
940     }
941   }
942 }
943
944 /**
945  * gst_structure_remove_fields:
946  * @structure: a #GstStructure
947  * @fieldname: the name of the field to remove
948  * @...: NULL-terminated list of more fieldnames to remove
949  *
950  * Removes the fields with the given names. If a field does not exist, the
951  * argument is ignored.
952  */
953 void
954 gst_structure_remove_fields (GstStructure * structure,
955     const gchar * fieldname, ...)
956 {
957   va_list varargs;
958
959   g_return_if_fail (structure != NULL);
960   g_return_if_fail (fieldname != NULL);
961   /* mutability checked in remove_field */
962
963   va_start (varargs, fieldname);
964   gst_structure_remove_fields_valist (structure, fieldname, varargs);
965   va_end (varargs);
966 }
967
968 /**
969  * gst_structure_remove_fields_valist:
970  * @structure: a #GstStructure
971  * @fieldname: the name of the field to remove
972  * @varargs: NULL-terminated list of more fieldnames to remove
973  *
974  * va_list form of gst_structure_remove_fields().
975  */
976 void
977 gst_structure_remove_fields_valist (GstStructure * structure,
978     const gchar * fieldname, va_list varargs)
979 {
980   gchar *field = (gchar *) fieldname;
981
982   g_return_if_fail (structure != NULL);
983   g_return_if_fail (fieldname != NULL);
984   /* mutability checked in remove_field */
985
986   while (field) {
987     gst_structure_remove_field (structure, field);
988     field = va_arg (varargs, char *);
989   }
990 }
991
992 /**
993  * gst_structure_remove_all_fields:
994  * @structure: a #GstStructure
995  *
996  * Removes all fields in a GstStructure.
997  */
998 void
999 gst_structure_remove_all_fields (GstStructure * structure)
1000 {
1001   GstStructureField *field;
1002   int i;
1003
1004   g_return_if_fail (structure != NULL);
1005   g_return_if_fail (IS_MUTABLE (structure));
1006
1007   for (i = GST_STRUCTURE_FIELDS (structure)->len - 1; i >= 0; i--) {
1008     field = GST_STRUCTURE_FIELD (structure, i);
1009
1010     if (G_IS_VALUE (&field->value)) {
1011       g_value_unset (&field->value);
1012     }
1013     GST_STRUCTURE_FIELDS (structure) =
1014         g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
1015   }
1016 }
1017
1018 /**
1019  * gst_structure_get_field_type:
1020  * @structure: a #GstStructure
1021  * @fieldname: the name of the field
1022  *
1023  * Finds the field with the given name, and returns the type of the
1024  * value it contains.  If the field is not found, G_TYPE_INVALID is
1025  * returned.
1026  *
1027  * Returns: the #GValue of the field
1028  */
1029 GType
1030 gst_structure_get_field_type (const GstStructure * structure,
1031     const gchar * fieldname)
1032 {
1033   GstStructureField *field;
1034
1035   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
1036   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
1037
1038   field = gst_structure_get_field (structure, fieldname);
1039   if (field == NULL)
1040     return G_TYPE_INVALID;
1041
1042   return G_VALUE_TYPE (&field->value);
1043 }
1044
1045 /**
1046  * gst_structure_n_fields:
1047  * @structure: a #GstStructure
1048  *
1049  * Get the number of fields in the structure.
1050  *
1051  * Returns: the number of fields in the structure
1052  */
1053 gint
1054 gst_structure_n_fields (const GstStructure * structure)
1055 {
1056   g_return_val_if_fail (structure != NULL, 0);
1057
1058   return GST_STRUCTURE_FIELDS (structure)->len;
1059 }
1060
1061 /**
1062  * gst_structure_nth_field_name:
1063  * @structure: a #GstStructure
1064  * @index: the index to get the name of
1065  *
1066  * Get the name of the given field number, counting from 0 onwards.
1067  *
1068  * Returns: the name of the given field number
1069  */
1070 const gchar *
1071 gst_structure_nth_field_name (const GstStructure * structure, guint index)
1072 {
1073   GstStructureField *field;
1074
1075   g_return_val_if_fail (structure != NULL, NULL);
1076   g_return_val_if_fail (index < GST_STRUCTURE_FIELDS (structure)->len, NULL);
1077
1078   field = GST_STRUCTURE_FIELD (structure, index);
1079
1080   return g_quark_to_string (field->name);
1081 }
1082
1083 /**
1084  * gst_structure_foreach:
1085  * @structure: a #GstStructure
1086  * @func: (scope call): a function to call for each field
1087  * @user_data: (closure): private data
1088  *
1089  * Calls the provided function once for each field in the #GstStructure. The
1090  * function must not modify the fields. Also see gst_structure_map_in_place().
1091  *
1092  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
1093  * FALSE otherwise.
1094  */
1095 gboolean
1096 gst_structure_foreach (const GstStructure * structure,
1097     GstStructureForeachFunc func, gpointer user_data)
1098 {
1099   guint i, len;
1100   GstStructureField *field;
1101   gboolean ret;
1102
1103   g_return_val_if_fail (structure != NULL, FALSE);
1104   g_return_val_if_fail (func != NULL, FALSE);
1105
1106   len = GST_STRUCTURE_FIELDS (structure)->len;
1107
1108   for (i = 0; i < len; i++) {
1109     field = GST_STRUCTURE_FIELD (structure, i);
1110
1111     ret = func (field->name, &field->value, user_data);
1112     if (G_UNLIKELY (!ret))
1113       return FALSE;
1114   }
1115
1116   return TRUE;
1117 }
1118
1119 /**
1120  * gst_structure_map_in_place:
1121  * @structure: a #GstStructure
1122  * @func: (scope call): a function to call for each field
1123  * @user_data: (closure): private data
1124  *
1125  * Calls the provided function once for each field in the #GstStructure. In
1126  * contrast to gst_structure_foreach(), the function may modify but not delete the
1127  * fields. The structure must be mutable.
1128  *
1129  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
1130  * FALSE otherwise.
1131  */
1132 gboolean
1133 gst_structure_map_in_place (GstStructure * structure,
1134     GstStructureMapFunc func, gpointer user_data)
1135 {
1136   guint i, len;
1137   GstStructureField *field;
1138   gboolean ret;
1139
1140   g_return_val_if_fail (structure != NULL, FALSE);
1141   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1142   g_return_val_if_fail (func != NULL, FALSE);
1143   len = GST_STRUCTURE_FIELDS (structure)->len;
1144
1145   for (i = 0; i < len; i++) {
1146     field = GST_STRUCTURE_FIELD (structure, i);
1147
1148     ret = func (field->name, &field->value, user_data);
1149     if (!ret)
1150       return FALSE;
1151   }
1152
1153   return TRUE;
1154 }
1155
1156 /**
1157  * gst_structure_id_has_field:
1158  * @structure: a #GstStructure
1159  * @field: #GQuark of the field name
1160  *
1161  * Check if @structure contains a field named @field.
1162  *
1163  * Returns: TRUE if the structure contains a field with the given name
1164  *
1165  * Since: 0.10.26
1166  */
1167 gboolean
1168 gst_structure_id_has_field (const GstStructure * structure, GQuark field)
1169 {
1170   GstStructureField *f;
1171
1172   g_return_val_if_fail (structure != NULL, FALSE);
1173   g_return_val_if_fail (field != 0, FALSE);
1174
1175   f = gst_structure_id_get_field (structure, field);
1176
1177   return (f != NULL);
1178 }
1179
1180 /**
1181  * gst_structure_has_field:
1182  * @structure: a #GstStructure
1183  * @fieldname: the name of a field
1184  *
1185  * Check if @structure contains a field named @fieldname.
1186  *
1187  * Returns: TRUE if the structure contains a field with the given name
1188  */
1189 gboolean
1190 gst_structure_has_field (const GstStructure * structure,
1191     const gchar * fieldname)
1192 {
1193   g_return_val_if_fail (structure != NULL, FALSE);
1194   g_return_val_if_fail (fieldname != NULL, FALSE);
1195
1196   return gst_structure_id_has_field (structure,
1197       g_quark_from_string (fieldname));
1198 }
1199
1200 /**
1201  * gst_structure_id_has_field_typed:
1202  * @structure: a #GstStructure
1203  * @field: #GQuark of the field name
1204  * @type: the type of a value
1205  *
1206  * Check if @structure contains a field named @field and with GType @type.
1207  *
1208  * Returns: TRUE if the structure contains a field with the given name and type
1209  *
1210  * Since: 0.10.26
1211  */
1212 gboolean
1213 gst_structure_id_has_field_typed (const GstStructure * structure,
1214     GQuark field, GType type)
1215 {
1216   GstStructureField *f;
1217
1218   g_return_val_if_fail (structure != NULL, FALSE);
1219   g_return_val_if_fail (field != 0, FALSE);
1220
1221   f = gst_structure_id_get_field (structure, field);
1222   if (f == NULL)
1223     return FALSE;
1224
1225   return (G_VALUE_TYPE (&f->value) == type);
1226 }
1227
1228 /**
1229  * gst_structure_has_field_typed:
1230  * @structure: a #GstStructure
1231  * @fieldname: the name of a field
1232  * @type: the type of a value
1233  *
1234  * Check if @structure contains a field named @fieldname and with GType @type.
1235  *
1236  * Returns: TRUE if the structure contains a field with the given name and type
1237  */
1238 gboolean
1239 gst_structure_has_field_typed (const GstStructure * structure,
1240     const gchar * fieldname, GType type)
1241 {
1242   g_return_val_if_fail (structure != NULL, FALSE);
1243   g_return_val_if_fail (fieldname != NULL, FALSE);
1244
1245   return gst_structure_id_has_field_typed (structure,
1246       g_quark_from_string (fieldname), type);
1247 }
1248
1249 /* utility functions */
1250
1251 /**
1252  * gst_structure_get_boolean:
1253  * @structure: a #GstStructure
1254  * @fieldname: the name of a field
1255  * @value: (out): a pointer to a #gboolean to set
1256  *
1257  * Sets the boolean pointed to by @value corresponding to the value of the
1258  * given field.  Caller is responsible for making sure the field exists
1259  * and has the correct type.
1260  *
1261  * Returns: TRUE if the value could be set correctly. If there was no field
1262  * with @fieldname or the existing field did not contain a boolean, this
1263  * function returns FALSE.
1264  */
1265 gboolean
1266 gst_structure_get_boolean (const GstStructure * structure,
1267     const gchar * fieldname, gboolean * value)
1268 {
1269   GstStructureField *field;
1270
1271   g_return_val_if_fail (structure != NULL, FALSE);
1272   g_return_val_if_fail (fieldname != NULL, FALSE);
1273
1274   field = gst_structure_get_field (structure, fieldname);
1275
1276   if (field == NULL)
1277     return FALSE;
1278   if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
1279     return FALSE;
1280
1281   *value = gst_g_value_get_boolean_unchecked (&field->value);
1282
1283   return TRUE;
1284 }
1285
1286 /**
1287  * gst_structure_get_int:
1288  * @structure: a #GstStructure
1289  * @fieldname: the name of a field
1290  * @value: (out): a pointer to an int to set
1291  *
1292  * Sets the int pointed to by @value corresponding to the value of the
1293  * given field.  Caller is responsible for making sure the field exists
1294  * and has the correct type.
1295  *
1296  * Returns: %TRUE if the value could be set correctly. If there was no field
1297  * with @fieldname or the existing field did not contain an int, this function
1298  * returns %FALSE.
1299  */
1300 gboolean
1301 gst_structure_get_int (const GstStructure * structure,
1302     const gchar * fieldname, gint * value)
1303 {
1304   GstStructureField *field;
1305
1306   g_return_val_if_fail (structure != NULL, FALSE);
1307   g_return_val_if_fail (fieldname != NULL, FALSE);
1308   g_return_val_if_fail (value != NULL, FALSE);
1309
1310   field = gst_structure_get_field (structure, fieldname);
1311
1312   if (field == NULL)
1313     return FALSE;
1314   if (!G_VALUE_HOLDS_INT (&field->value))
1315     return FALSE;
1316
1317   *value = gst_g_value_get_int_unchecked (&field->value);
1318
1319   return TRUE;
1320 }
1321
1322 /**
1323  * gst_structure_get_uint:
1324  * @structure: a #GstStructure
1325  * @fieldname: the name of a field
1326  * @value: (out): a pointer to a uint to set
1327  *
1328  * Sets the uint pointed to by @value corresponding to the value of the
1329  * given field.  Caller is responsible for making sure the field exists
1330  * and has the correct type.
1331  *
1332  * Returns: %TRUE if the value could be set correctly. If there was no field
1333  * with @fieldname or the existing field did not contain a uint, this function
1334  * returns %FALSE.
1335  *
1336  * Since: 0.10.15
1337  */
1338 gboolean
1339 gst_structure_get_uint (const GstStructure * structure,
1340     const gchar * fieldname, guint * value)
1341 {
1342   GstStructureField *field;
1343
1344   g_return_val_if_fail (structure != NULL, FALSE);
1345   g_return_val_if_fail (fieldname != NULL, FALSE);
1346   g_return_val_if_fail (value != NULL, FALSE);
1347
1348   field = gst_structure_get_field (structure, fieldname);
1349
1350   if (field == NULL)
1351     return FALSE;
1352   if (!G_VALUE_HOLDS_UINT (&field->value))
1353     return FALSE;
1354
1355   *value = gst_g_value_get_uint_unchecked (&field->value);
1356
1357   return TRUE;
1358 }
1359
1360 /**
1361  * gst_structure_get_date:
1362  * @structure: a #GstStructure
1363  * @fieldname: the name of a field
1364  * @value: (out callee-allocates): a pointer to a #GDate to set
1365  *
1366  * Sets the date pointed to by @value corresponding to the date of the
1367  * given field.  Caller is responsible for making sure the field exists
1368  * and has the correct type.
1369  *
1370  * On success @value will point to a newly-allocated copy of the date which
1371  * should be freed with g_date_free() when no longer needed (note: this is
1372  * inconsistent with e.g. gst_structure_get_string() which doesn't return a
1373  * copy of the string).
1374  *
1375  * Returns: TRUE if the value could be set correctly. If there was no field
1376  * with @fieldname or the existing field did not contain a data, this function
1377  * returns FALSE.
1378  */
1379 gboolean
1380 gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
1381     GDate ** value)
1382 {
1383   GstStructureField *field;
1384
1385   g_return_val_if_fail (structure != NULL, FALSE);
1386   g_return_val_if_fail (fieldname != NULL, FALSE);
1387   g_return_val_if_fail (value != NULL, FALSE);
1388
1389   field = gst_structure_get_field (structure, fieldname);
1390
1391   if (field == NULL)
1392     return FALSE;
1393   if (!G_VALUE_HOLDS (&field->value, G_TYPE_DATE))
1394     return FALSE;
1395
1396   /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */
1397   *value = g_value_dup_boxed (&field->value);
1398
1399   return TRUE;
1400 }
1401
1402 /**
1403  * gst_structure_get_date_time:
1404  * @structure: a #GstStructure
1405  * @fieldname: the name of a field
1406  * @value: (out callee-allocates): a pointer to a #GstDateTime to set
1407  *
1408  * Sets the datetime pointed to by @value corresponding to the datetime of the
1409  * given field. Caller is responsible for making sure the field exists
1410  * and has the correct type.
1411  *
1412  * On success @value will point to a reference of the datetime which
1413  * should be unreffed with gst_date_time_unref() when no longer needed
1414  * (note: this is inconsistent with e.g. gst_structure_get_string()
1415  * which doesn't return a copy of the string).
1416  *
1417  * Returns: TRUE if the value could be set correctly. If there was no field
1418  * with @fieldname or the existing field did not contain a data, this function
1419  * returns FALSE.
1420  *
1421  * Since: 0.10.31
1422  */
1423 gboolean
1424 gst_structure_get_date_time (const GstStructure * structure,
1425     const gchar * fieldname, GstDateTime ** value)
1426 {
1427   GstStructureField *field;
1428
1429   g_return_val_if_fail (structure != NULL, FALSE);
1430   g_return_val_if_fail (fieldname != NULL, FALSE);
1431   g_return_val_if_fail (value != NULL, FALSE);
1432
1433   field = gst_structure_get_field (structure, fieldname);
1434
1435   if (field == NULL)
1436     return FALSE;
1437   if (!GST_VALUE_HOLDS_DATE_TIME (&field->value))
1438     return FALSE;
1439
1440   /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */
1441   *value = g_value_dup_boxed (&field->value);
1442
1443   return TRUE;
1444 }
1445
1446 /**
1447  * gst_structure_get_clock_time:
1448  * @structure: a #GstStructure
1449  * @fieldname: the name of a field
1450  * @value: (out): a pointer to a #GstClockTime to set
1451  *
1452  * Sets the clock time pointed to by @value corresponding to the clock time
1453  * of the given field.  Caller is responsible for making sure the field exists
1454  * and has the correct type.
1455  *
1456  * Returns: TRUE if the value could be set correctly. If there was no field
1457  * with @fieldname or the existing field did not contain a #GstClockTime, this
1458  * function returns FALSE.
1459  */
1460 gboolean
1461 gst_structure_get_clock_time (const GstStructure * structure,
1462     const gchar * fieldname, GstClockTime * value)
1463 {
1464   GstStructureField *field;
1465
1466   g_return_val_if_fail (structure != NULL, FALSE);
1467   g_return_val_if_fail (fieldname != NULL, FALSE);
1468   g_return_val_if_fail (value != NULL, FALSE);
1469
1470   field = gst_structure_get_field (structure, fieldname);
1471
1472   if (field == NULL)
1473     return FALSE;
1474   if (!G_VALUE_HOLDS_UINT64 (&field->value))
1475     return FALSE;
1476
1477   *value = gst_g_value_get_uint64_unchecked (&field->value);
1478
1479   return TRUE;
1480 }
1481
1482 /**
1483  * gst_structure_get_double:
1484  * @structure: a #GstStructure
1485  * @fieldname: the name of a field
1486  * @value: (out): a pointer to a gdouble to set
1487  *
1488  * Sets the double pointed to by @value corresponding to the value of the
1489  * given field.  Caller is responsible for making sure the field exists
1490  * and has the correct type.
1491  *
1492  * Returns: TRUE if the value could be set correctly. If there was no field
1493  * with @fieldname or the existing field did not contain a double, this
1494  * function returns FALSE.
1495  */
1496 gboolean
1497 gst_structure_get_double (const GstStructure * structure,
1498     const gchar * fieldname, gdouble * value)
1499 {
1500   GstStructureField *field;
1501
1502   g_return_val_if_fail (structure != NULL, FALSE);
1503   g_return_val_if_fail (fieldname != NULL, FALSE);
1504   g_return_val_if_fail (value != NULL, FALSE);
1505
1506   field = gst_structure_get_field (structure, fieldname);
1507
1508   if (field == NULL)
1509     return FALSE;
1510   if (!G_VALUE_HOLDS_DOUBLE (&field->value))
1511     return FALSE;
1512
1513   *value = gst_g_value_get_double_unchecked (&field->value);
1514
1515   return TRUE;
1516 }
1517
1518 /**
1519  * gst_structure_get_string:
1520  * @structure: a #GstStructure
1521  * @fieldname: the name of a field
1522  *
1523  * Finds the field corresponding to @fieldname, and returns the string
1524  * contained in the field's value.  Caller is responsible for making
1525  * sure the field exists and has the correct type.
1526  *
1527  * The string should not be modified, and remains valid until the next
1528  * call to a gst_structure_*() function with the given structure.
1529  *
1530  * Returns: a pointer to the string or NULL when the field did not exist
1531  * or did not contain a string.
1532  */
1533 const gchar *
1534 gst_structure_get_string (const GstStructure * structure,
1535     const gchar * fieldname)
1536 {
1537   GstStructureField *field;
1538
1539   g_return_val_if_fail (structure != NULL, NULL);
1540   g_return_val_if_fail (fieldname != NULL, NULL);
1541
1542   field = gst_structure_get_field (structure, fieldname);
1543
1544   if (field == NULL)
1545     return NULL;
1546   if (!G_VALUE_HOLDS_STRING (&field->value))
1547     return NULL;
1548
1549   return gst_g_value_get_string_unchecked (&field->value);
1550 }
1551
1552 /**
1553  * gst_structure_get_enum:
1554  * @structure: a #GstStructure
1555  * @fieldname: the name of a field
1556  * @enumtype: the enum type of a field
1557  * @value: (out): a pointer to an int to set
1558  *
1559  * Sets the int pointed to by @value corresponding to the value of the
1560  * given field.  Caller is responsible for making sure the field exists,
1561  * has the correct type and that the enumtype is correct.
1562  *
1563  * Returns: TRUE if the value could be set correctly. If there was no field
1564  * with @fieldname or the existing field did not contain an enum of the given
1565  * type, this function returns FALSE.
1566  */
1567 gboolean
1568 gst_structure_get_enum (const GstStructure * structure,
1569     const gchar * fieldname, GType enumtype, gint * value)
1570 {
1571   GstStructureField *field;
1572
1573   g_return_val_if_fail (structure != NULL, FALSE);
1574   g_return_val_if_fail (fieldname != NULL, FALSE);
1575   g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
1576   g_return_val_if_fail (value != NULL, FALSE);
1577
1578   field = gst_structure_get_field (structure, fieldname);
1579
1580   if (field == NULL)
1581     return FALSE;
1582   if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
1583     return FALSE;
1584
1585   *value = g_value_get_enum (&field->value);
1586
1587   return TRUE;
1588 }
1589
1590 /**
1591  * gst_structure_get_fraction:
1592  * @structure: a #GstStructure
1593  * @fieldname: the name of a field
1594  * @value_numerator: (out): a pointer to an int to set
1595  * @value_denominator: (out): a pointer to an int to set
1596  *
1597  * Sets the integers pointed to by @value_numerator and @value_denominator
1598  * corresponding to the value of the given field.  Caller is responsible
1599  * for making sure the field exists and has the correct type.
1600  *
1601  * Returns: TRUE if the values could be set correctly. If there was no field
1602  * with @fieldname or the existing field did not contain a GstFraction, this
1603  * function returns FALSE.
1604  */
1605 gboolean
1606 gst_structure_get_fraction (const GstStructure * structure,
1607     const gchar * fieldname, gint * value_numerator, gint * value_denominator)
1608 {
1609   GstStructureField *field;
1610
1611   g_return_val_if_fail (structure != NULL, FALSE);
1612   g_return_val_if_fail (fieldname != NULL, FALSE);
1613   g_return_val_if_fail (value_numerator != NULL, FALSE);
1614   g_return_val_if_fail (value_denominator != NULL, FALSE);
1615
1616   field = gst_structure_get_field (structure, fieldname);
1617
1618   if (field == NULL)
1619     return FALSE;
1620   if (!GST_VALUE_HOLDS_FRACTION (&field->value))
1621     return FALSE;
1622
1623   *value_numerator = gst_value_get_fraction_numerator (&field->value);
1624   *value_denominator = gst_value_get_fraction_denominator (&field->value);
1625
1626   return TRUE;
1627 }
1628
1629 typedef struct _GstStructureAbbreviation
1630 {
1631   const gchar *type_name;
1632   GType type;
1633 }
1634 GstStructureAbbreviation;
1635
1636 /* return a copy of an array of GstStructureAbbreviation containing all the
1637  * known type_string, GType maps, including abbreviations for common types */
1638 static GstStructureAbbreviation *
1639 gst_structure_get_abbrs (gint * n_abbrs)
1640 {
1641   static GstStructureAbbreviation *abbrs = NULL;
1642   static volatile gsize num = 0;
1643
1644   if (g_once_init_enter (&num)) {
1645     /* dynamically generate the array */
1646     gsize _num;
1647     GstStructureAbbreviation dyn_abbrs[] = {
1648       {"int", G_TYPE_INT}
1649       ,
1650       {"i", G_TYPE_INT}
1651       ,
1652       {"uint", G_TYPE_UINT}
1653       ,
1654       {"u", G_TYPE_UINT}
1655       ,
1656       {"float", G_TYPE_FLOAT}
1657       ,
1658       {"f", G_TYPE_FLOAT}
1659       ,
1660       {"double", G_TYPE_DOUBLE}
1661       ,
1662       {"d", G_TYPE_DOUBLE}
1663       ,
1664       {"buffer", GST_TYPE_BUFFER}
1665       ,
1666       {"fraction", GST_TYPE_FRACTION}
1667       ,
1668       {"boolean", G_TYPE_BOOLEAN}
1669       ,
1670       {"bool", G_TYPE_BOOLEAN}
1671       ,
1672       {"b", G_TYPE_BOOLEAN}
1673       ,
1674       {"string", G_TYPE_STRING}
1675       ,
1676       {"str", G_TYPE_STRING}
1677       ,
1678       {"s", G_TYPE_STRING}
1679       ,
1680       {"structure", GST_TYPE_STRUCTURE}
1681       ,
1682       {"date", G_TYPE_DATE}
1683       ,
1684       {"datetime", GST_TYPE_DATE_TIME}
1685       ,
1686       {"bitmask", GST_TYPE_BITMASK}
1687     };
1688     _num = G_N_ELEMENTS (dyn_abbrs);
1689     /* permanently allocate and copy the array now */
1690     abbrs = g_new0 (GstStructureAbbreviation, _num);
1691     memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * _num);
1692     g_once_init_leave (&num, _num);
1693   }
1694   *n_abbrs = num;
1695
1696   return abbrs;
1697 }
1698
1699 /* given a type_name that could be a type abbreviation or a registered GType,
1700  * return a matching GType */
1701 static GType
1702 gst_structure_gtype_from_abbr (const char *type_name)
1703 {
1704   int i;
1705   GstStructureAbbreviation *abbrs;
1706   gint n_abbrs;
1707
1708   g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1709
1710   abbrs = gst_structure_get_abbrs (&n_abbrs);
1711
1712   for (i = 0; i < n_abbrs; i++) {
1713     if (strcmp (type_name, abbrs[i].type_name) == 0) {
1714       return abbrs[i].type;
1715     }
1716   }
1717
1718   /* this is the fallback */
1719   return g_type_from_name (type_name);
1720 }
1721
1722 static const char *
1723 gst_structure_to_abbr (GType type)
1724 {
1725   int i;
1726   GstStructureAbbreviation *abbrs;
1727   gint n_abbrs;
1728
1729   g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1730
1731   abbrs = gst_structure_get_abbrs (&n_abbrs);
1732
1733   for (i = 0; i < n_abbrs; i++) {
1734     if (type == abbrs[i].type) {
1735       return abbrs[i].type_name;
1736     }
1737   }
1738
1739   return g_type_name (type);
1740 }
1741
1742 static GType
1743 gst_structure_value_get_generic_type (GValue * val)
1744 {
1745   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1746       || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1747     GArray *array = g_value_peek_pointer (val);
1748
1749     if (array->len > 0) {
1750       GValue *value = &g_array_index (array, GValue, 0);
1751
1752       return gst_structure_value_get_generic_type (value);
1753     } else {
1754       return G_TYPE_INT;
1755     }
1756   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1757     return G_TYPE_INT;
1758   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT64_RANGE) {
1759     return G_TYPE_INT64;
1760   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1761     return G_TYPE_DOUBLE;
1762   } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
1763     return GST_TYPE_FRACTION;
1764   }
1765   return G_VALUE_TYPE (val);
1766 }
1767
1768 gboolean
1769 priv_gst_structure_append_to_gstring (const GstStructure * structure,
1770     GString * s)
1771 {
1772   GstStructureField *field;
1773   guint i, len;
1774
1775   g_return_val_if_fail (s != NULL, FALSE);
1776
1777   g_string_append (s, g_quark_to_string (structure->name));
1778   len = GST_STRUCTURE_FIELDS (structure)->len;
1779   for (i = 0; i < len; i++) {
1780     char *t;
1781     GType type;
1782
1783     field = GST_STRUCTURE_FIELD (structure, i);
1784
1785     t = gst_value_serialize (&field->value);
1786     type = gst_structure_value_get_generic_type (&field->value);
1787
1788     g_string_append_len (s, ", ", 2);
1789     /* FIXME: do we need to escape fieldnames? */
1790     g_string_append (s, g_quark_to_string (field->name));
1791     g_string_append_len (s, "=(", 2);
1792     g_string_append (s, gst_structure_to_abbr (type));
1793     g_string_append_c (s, ')');
1794     g_string_append (s, t == NULL ? "NULL" : t);
1795     g_free (t);
1796   }
1797
1798   g_string_append_c (s, ';');
1799   return TRUE;
1800 }
1801
1802 /**
1803  * gst_structure_to_string:
1804  * @structure: a #GstStructure
1805  *
1806  * Converts @structure to a human-readable string representation.
1807  *
1808  * For debugging purposes its easier to do something like this:
1809  * |[
1810  * GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
1811  * ]|
1812  * This prints the structure in human readble form.
1813  *
1814  * Free-function: g_free
1815  *
1816  * Returns: (transfer full)L a pointer to string allocated by g_malloc().
1817  *     g_free() after usage.
1818  */
1819 gchar *
1820 gst_structure_to_string (const GstStructure * structure)
1821 {
1822   GString *s;
1823
1824   /* NOTE:  This function is potentially called by the debug system,
1825    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1826    * should be careful to avoid recursion.  This includes any functions
1827    * called by gst_structure_to_string.  In particular, calls should
1828    * not use the GST_PTR_FORMAT extension.  */
1829
1830   g_return_val_if_fail (structure != NULL, NULL);
1831
1832   /* we estimate a minimum size based on the number of fields in order to
1833    * avoid unnecessary reallocs within GString */
1834   s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure));
1835   priv_gst_structure_append_to_gstring (structure, s);
1836   return g_string_free (s, FALSE);
1837 }
1838
1839 /*
1840  * r will still point to the string. if end == next, the string will not be
1841  * null-terminated. In all other cases it will be.
1842  * end = pointer to char behind end of string, next = pointer to start of
1843  * unread data.
1844  * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1845  */
1846 static gboolean
1847 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next,
1848     gboolean unescape)
1849 {
1850   gchar *w;
1851
1852   if (*s == 0)
1853     return FALSE;
1854
1855   if (*s != '"') {
1856     int ret;
1857
1858     ret = gst_structure_parse_simple_string (s, end);
1859     *next = *end;
1860
1861     return ret;
1862   }
1863
1864   if (unescape) {
1865     w = s;
1866     s++;
1867     while (*s != '"') {
1868       if (G_UNLIKELY (*s == 0))
1869         return FALSE;
1870       if (G_UNLIKELY (*s == '\\'))
1871         s++;
1872       *w = *s;
1873       w++;
1874       s++;
1875     }
1876     s++;
1877   } else {
1878     /* Find the closing quotes */
1879     s++;
1880     while (*s != '"') {
1881       if (G_UNLIKELY (*s == 0))
1882         return FALSE;
1883       if (G_UNLIKELY (*s == '\\'))
1884         s++;
1885       s++;
1886     }
1887     s++;
1888     w = s;
1889   }
1890
1891   *end = w;
1892   *next = s;
1893
1894   return TRUE;
1895 }
1896
1897 static gboolean
1898 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1899     GType type)
1900 {
1901   GValue value1 = { 0 };
1902   GValue value2 = { 0 };
1903   GValue value3 = { 0 };
1904   GType range_type;
1905   gboolean ret, have_step = FALSE;
1906
1907   if (*s != '[')
1908     return FALSE;
1909   s++;
1910
1911   ret = gst_structure_parse_value (s, &s, &value1, type);
1912   if (ret == FALSE)
1913     return FALSE;
1914
1915   while (g_ascii_isspace (*s))
1916     s++;
1917
1918   if (*s != ',')
1919     return FALSE;
1920   s++;
1921
1922   while (g_ascii_isspace (*s))
1923     s++;
1924
1925   ret = gst_structure_parse_value (s, &s, &value2, type);
1926   if (ret == FALSE)
1927     return FALSE;
1928
1929   while (g_ascii_isspace (*s))
1930     s++;
1931
1932   /* optional step for int and int64 */
1933   if (G_VALUE_TYPE (&value1) == G_TYPE_INT
1934       || G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
1935     if (*s == ',') {
1936       s++;
1937
1938       while (g_ascii_isspace (*s))
1939         s++;
1940
1941       ret = gst_structure_parse_value (s, &s, &value3, type);
1942       if (ret == FALSE)
1943         return FALSE;
1944
1945       while (g_ascii_isspace (*s))
1946         s++;
1947
1948       have_step = TRUE;
1949     }
1950   }
1951
1952   if (*s != ']')
1953     return FALSE;
1954   s++;
1955
1956   if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1957     return FALSE;
1958   if (have_step && G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value3))
1959     return FALSE;
1960
1961   if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1962     range_type = GST_TYPE_DOUBLE_RANGE;
1963     g_value_init (value, range_type);
1964     gst_value_set_double_range (value,
1965         gst_g_value_get_double_unchecked (&value1),
1966         gst_g_value_get_double_unchecked (&value2));
1967   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1968     range_type = GST_TYPE_INT_RANGE;
1969     g_value_init (value, range_type);
1970     if (have_step)
1971       gst_value_set_int_range_step (value,
1972           gst_g_value_get_int_unchecked (&value1),
1973           gst_g_value_get_int_unchecked (&value2),
1974           gst_g_value_get_int_unchecked (&value3));
1975     else
1976       gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1),
1977           gst_g_value_get_int_unchecked (&value2));
1978   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
1979     range_type = GST_TYPE_INT64_RANGE;
1980     g_value_init (value, range_type);
1981     if (have_step)
1982       gst_value_set_int64_range_step (value,
1983           gst_g_value_get_int64_unchecked (&value1),
1984           gst_g_value_get_int64_unchecked (&value2),
1985           gst_g_value_get_int64_unchecked (&value3));
1986     else
1987       gst_value_set_int64_range (value,
1988           gst_g_value_get_int64_unchecked (&value1),
1989           gst_g_value_get_int64_unchecked (&value2));
1990   } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
1991     range_type = GST_TYPE_FRACTION_RANGE;
1992     g_value_init (value, range_type);
1993     gst_value_set_fraction_range (value, &value1, &value2);
1994   } else {
1995     return FALSE;
1996   }
1997
1998   *after = s;
1999   return TRUE;
2000 }
2001
2002 static gboolean
2003 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
2004     GType type, GType list_type, char begin, char end)
2005 {
2006   GValue list_value = { 0 };
2007   gboolean ret;
2008   GArray *array;
2009
2010   g_value_init (value, list_type);
2011   array = g_value_peek_pointer (value);
2012
2013   if (*s != begin)
2014     return FALSE;
2015   s++;
2016
2017   while (g_ascii_isspace (*s))
2018     s++;
2019   if (*s == end) {
2020     s++;
2021     *after = s;
2022     return TRUE;
2023   }
2024
2025   ret = gst_structure_parse_value (s, &s, &list_value, type);
2026   if (ret == FALSE)
2027     return FALSE;
2028
2029   g_array_append_val (array, list_value);
2030
2031   while (g_ascii_isspace (*s))
2032     s++;
2033
2034   while (*s != end) {
2035     if (*s != ',')
2036       return FALSE;
2037     s++;
2038
2039     while (g_ascii_isspace (*s))
2040       s++;
2041
2042     memset (&list_value, 0, sizeof (list_value));
2043     ret = gst_structure_parse_value (s, &s, &list_value, type);
2044     if (ret == FALSE)
2045       return FALSE;
2046
2047     g_array_append_val (array, list_value);
2048     while (g_ascii_isspace (*s))
2049       s++;
2050   }
2051
2052   s++;
2053
2054   *after = s;
2055   return TRUE;
2056 }
2057
2058 static gboolean
2059 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
2060 {
2061   return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
2062       '{', '}');
2063 }
2064
2065 static gboolean
2066 gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
2067     GType type)
2068 {
2069   return gst_structure_parse_any_list (s, after, value, type,
2070       GST_TYPE_ARRAY, '<', '>');
2071 }
2072
2073 static gboolean
2074 gst_structure_parse_simple_string (gchar * str, gchar ** end)
2075 {
2076   char *s = str;
2077
2078   while (G_LIKELY (GST_ASCII_IS_STRING (*s))) {
2079     s++;
2080   }
2081
2082   *end = s;
2083
2084   return (s != str);
2085 }
2086
2087 static gboolean
2088 gst_structure_parse_field (gchar * str,
2089     gchar ** after, GstStructureField * field)
2090 {
2091   gchar *name;
2092   gchar *name_end;
2093   gchar *s;
2094   gchar c;
2095
2096   s = str;
2097
2098   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
2099     s++;
2100   name = s;
2101   if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &name_end))) {
2102     GST_WARNING ("failed to parse simple string, str=%s", str);
2103     return FALSE;
2104   }
2105
2106   s = name_end;
2107   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
2108     s++;
2109
2110   if (G_UNLIKELY (*s != '=')) {
2111     GST_WARNING ("missing assignment operator in the field, str=%s", str);
2112     return FALSE;
2113   }
2114   s++;
2115
2116   c = *name_end;
2117   *name_end = '\0';
2118   field->name = g_quark_from_string (name);
2119   GST_DEBUG ("trying field name '%s'", name);
2120   *name_end = c;
2121
2122   if (G_UNLIKELY (!gst_structure_parse_value (s, &s, &field->value,
2123               G_TYPE_INVALID))) {
2124     GST_WARNING ("failed to parse value %s", str);
2125     return FALSE;
2126   }
2127
2128   *after = s;
2129   return TRUE;
2130 }
2131
2132 static gboolean
2133 gst_structure_parse_value (gchar * str,
2134     gchar ** after, GValue * value, GType default_type)
2135 {
2136   gchar *type_name;
2137   gchar *type_end;
2138   gchar *value_s;
2139   gchar *value_end;
2140   gchar *s;
2141   gchar c;
2142   int ret = 0;
2143   GType type = default_type;
2144
2145   s = str;
2146   while (g_ascii_isspace (*s))
2147     s++;
2148
2149   /* check if there's a (type_name) 'cast' */
2150   type_name = NULL;
2151   if (*s == '(') {
2152     s++;
2153     while (g_ascii_isspace (*s))
2154       s++;
2155     type_name = s;
2156     if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &type_end)))
2157       return FALSE;
2158     s = type_end;
2159     while (g_ascii_isspace (*s))
2160       s++;
2161     if (G_UNLIKELY (*s != ')'))
2162       return FALSE;
2163     s++;
2164     while (g_ascii_isspace (*s))
2165       s++;
2166
2167     c = *type_end;
2168     *type_end = 0;
2169     type = gst_structure_gtype_from_abbr (type_name);
2170     GST_DEBUG ("trying type name '%s'", type_name);
2171     *type_end = c;
2172
2173     if (G_UNLIKELY (type == G_TYPE_INVALID)) {
2174       GST_WARNING ("invalid type");
2175       return FALSE;
2176     }
2177   }
2178
2179   while (g_ascii_isspace (*s))
2180     s++;
2181   if (*s == '[') {
2182     ret = gst_structure_parse_range (s, &s, value, type);
2183   } else if (*s == '{') {
2184     ret = gst_structure_parse_list (s, &s, value, type);
2185   } else if (*s == '<') {
2186     ret = gst_structure_parse_array (s, &s, value, type);
2187   } else {
2188     value_s = s;
2189
2190     if (G_UNLIKELY (type == G_TYPE_INVALID)) {
2191       GType try_types[] =
2192           { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
2193         G_TYPE_STRING
2194       };
2195       int i;
2196
2197       if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s, TRUE)))
2198         return FALSE;
2199       /* Set NULL terminator for deserialization */
2200       c = *value_end;
2201       *value_end = '\0';
2202
2203       for (i = 0; i < G_N_ELEMENTS (try_types); i++) {
2204         g_value_init (value, try_types[i]);
2205         ret = gst_value_deserialize (value, value_s);
2206         if (ret)
2207           break;
2208         g_value_unset (value);
2209       }
2210     } else {
2211       g_value_init (value, type);
2212
2213       if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s,
2214                   (type != G_TYPE_STRING))))
2215         return FALSE;
2216       /* Set NULL terminator for deserialization */
2217       c = *value_end;
2218       *value_end = '\0';
2219
2220       ret = gst_value_deserialize (value, value_s);
2221       if (G_UNLIKELY (!ret))
2222         g_value_unset (value);
2223     }
2224     *value_end = c;
2225   }
2226
2227   *after = s;
2228
2229   return ret;
2230 }
2231
2232 /**
2233  * gst_structure_from_string:
2234  * @string: a string representation of a #GstStructure.
2235  * @end: (out) (allow-none) (transfer none): pointer to store the end of the string in.
2236  *
2237  * Creates a #GstStructure from a string representation.
2238  * If end is not NULL, a pointer to the place inside the given string
2239  * where parsing ended will be returned.
2240  *
2241  * Free-function: gst_structure_free
2242  *
2243  * Returns: (transfer full): a new #GstStructure or NULL when the string could
2244  *     not be parsed. Free with gst_structure_free() after use.
2245  */
2246 GstStructure *
2247 gst_structure_from_string (const gchar * string, gchar ** end)
2248 {
2249   char *name;
2250   char *copy;
2251   char *w;
2252   char *r;
2253   char save;
2254   GstStructure *structure = NULL;
2255   GstStructureField field;
2256
2257   g_return_val_if_fail (string != NULL, NULL);
2258
2259   copy = g_strdup (string);
2260   r = copy;
2261
2262   /* skip spaces (FIXME: _isspace treats tabs and newlines as space!) */
2263   while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2264               && g_ascii_isspace (r[1]))))
2265     r++;
2266
2267   name = r;
2268   if (G_UNLIKELY (!gst_structure_parse_string (r, &w, &r, TRUE))) {
2269     GST_WARNING ("Failed to parse structure string '%s'", string);
2270     goto error;
2271   }
2272
2273   save = *w;
2274   *w = '\0';
2275   structure = gst_structure_new_empty (name);
2276   *w = save;
2277
2278   if (G_UNLIKELY (structure == NULL))
2279     goto error;
2280
2281   do {
2282     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2283                 && g_ascii_isspace (r[1]))))
2284       r++;
2285     if (*r == ';') {
2286       /* end of structure, get the next char and finish */
2287       r++;
2288       break;
2289     }
2290     if (*r == '\0') {
2291       /* accept \0 as end delimiter */
2292       break;
2293     }
2294     if (G_UNLIKELY (*r != ',')) {
2295       GST_WARNING ("Failed to find delimiter, r=%s", r);
2296       goto error;
2297     }
2298     r++;
2299     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2300                 && g_ascii_isspace (r[1]))))
2301       r++;
2302
2303     memset (&field, 0, sizeof (field));
2304     if (G_UNLIKELY (!gst_structure_parse_field (r, &r, &field))) {
2305       GST_WARNING ("Failed to parse field, r=%s", r);
2306       goto error;
2307     }
2308     gst_structure_set_field (structure, &field);
2309   } while (TRUE);
2310
2311   if (end)
2312     *end = (char *) string + (r - copy);
2313   else if (*r)
2314     g_warning ("gst_structure_from_string did not consume whole string,"
2315         " but caller did not provide end pointer (\"%s\")", string);
2316
2317   g_free (copy);
2318   return structure;
2319
2320 error:
2321   if (structure)
2322     gst_structure_free (structure);
2323   g_free (copy);
2324   return NULL;
2325 }
2326
2327 static void
2328 gst_structure_transform_to_string (const GValue * src_value,
2329     GValue * dest_value)
2330 {
2331   g_return_if_fail (src_value != NULL);
2332   g_return_if_fail (dest_value != NULL);
2333
2334   dest_value->data[0].v_pointer =
2335       gst_structure_to_string (src_value->data[0].v_pointer);
2336 }
2337
2338 static GstStructure *
2339 gst_structure_copy_conditional (const GstStructure * structure)
2340 {
2341   if (structure)
2342     return gst_structure_copy (structure);
2343   return NULL;
2344 }
2345
2346 /* fixate utility functions */
2347
2348 /**
2349  * gst_structure_fixate_field_nearest_int:
2350  * @structure: a #GstStructure
2351  * @field_name: a field in @structure
2352  * @target: the target value of the fixation
2353  *
2354  * Fixates a #GstStructure by changing the given field to the nearest
2355  * integer to @target that is a subset of the existing field.
2356  *
2357  * Returns: TRUE if the structure could be fixated
2358  */
2359 gboolean
2360 gst_structure_fixate_field_nearest_int (GstStructure * structure,
2361     const char *field_name, int target)
2362 {
2363   const GValue *value;
2364
2365   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2366   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2367
2368   value = gst_structure_get_value (structure, field_name);
2369
2370   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
2371     /* already fixed */
2372     return FALSE;
2373   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
2374     int x;
2375
2376     x = gst_value_get_int_range_min (value);
2377     if (target < x)
2378       target = x;
2379     x = gst_value_get_int_range_max (value);
2380     if (target > x)
2381       target = x;
2382     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
2383     return TRUE;
2384   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2385     const GValue *list_value;
2386     int i, n;
2387     int best = 0;
2388     int best_index = -1;
2389
2390     n = gst_value_list_get_size (value);
2391     for (i = 0; i < n; i++) {
2392       list_value = gst_value_list_get_value (value, i);
2393       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
2394         int x = gst_g_value_get_int_unchecked (list_value);
2395
2396         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2397           best_index = i;
2398           best = x;
2399         }
2400       }
2401     }
2402     if (best_index != -1) {
2403       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
2404       return TRUE;
2405     }
2406     return FALSE;
2407   }
2408
2409   return FALSE;
2410 }
2411
2412 /**
2413  * gst_structure_fixate_field_nearest_double:
2414  * @structure: a #GstStructure
2415  * @field_name: a field in @structure
2416  * @target: the target value of the fixation
2417  *
2418  * Fixates a #GstStructure by changing the given field to the nearest
2419  * double to @target that is a subset of the existing field.
2420  *
2421  * Returns: TRUE if the structure could be fixated
2422  */
2423 gboolean
2424 gst_structure_fixate_field_nearest_double (GstStructure * structure,
2425     const char *field_name, double target)
2426 {
2427   const GValue *value;
2428
2429   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2430   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2431
2432   value = gst_structure_get_value (structure, field_name);
2433
2434   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
2435     /* already fixed */
2436     return FALSE;
2437   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
2438     double x;
2439
2440     x = gst_value_get_double_range_min (value);
2441     if (target < x)
2442       target = x;
2443     x = gst_value_get_double_range_max (value);
2444     if (target > x)
2445       target = x;
2446     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
2447     return TRUE;
2448   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2449     const GValue *list_value;
2450     int i, n;
2451     double best = 0;
2452     int best_index = -1;
2453
2454     n = gst_value_list_get_size (value);
2455     for (i = 0; i < n; i++) {
2456       list_value = gst_value_list_get_value (value, i);
2457       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
2458         double x = gst_g_value_get_double_unchecked (list_value);
2459
2460         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2461           best_index = i;
2462           best = x;
2463         }
2464       }
2465     }
2466     if (best_index != -1) {
2467       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
2468       return TRUE;
2469     }
2470     return FALSE;
2471   }
2472
2473   return FALSE;
2474
2475 }
2476
2477 /**
2478  * gst_structure_fixate_field_boolean:
2479  * @structure: a #GstStructure
2480  * @field_name: a field in @structure
2481  * @target: the target value of the fixation
2482  *
2483  * Fixates a #GstStructure by changing the given @field_name field to the given
2484  * @target boolean if that field is not fixed yet.
2485  *
2486  * Returns: TRUE if the structure could be fixated
2487  */
2488 gboolean
2489 gst_structure_fixate_field_boolean (GstStructure * structure,
2490     const char *field_name, gboolean target)
2491 {
2492   const GValue *value;
2493
2494   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2495   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2496
2497   value = gst_structure_get_value (structure, field_name);
2498
2499   if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
2500     /* already fixed */
2501     return FALSE;
2502   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2503     const GValue *list_value;
2504     int i, n;
2505     int best = 0;
2506     int best_index = -1;
2507
2508     n = gst_value_list_get_size (value);
2509     for (i = 0; i < n; i++) {
2510       list_value = gst_value_list_get_value (value, i);
2511       if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
2512         gboolean x = gst_g_value_get_boolean_unchecked (list_value);
2513
2514         if (best_index == -1 || x == target) {
2515           best_index = i;
2516           best = x;
2517         }
2518       }
2519     }
2520     if (best_index != -1) {
2521       gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
2522       return TRUE;
2523     }
2524     return FALSE;
2525   }
2526
2527   return FALSE;
2528 }
2529
2530 /**
2531  * gst_structure_fixate_field_string:
2532  * @structure: a #GstStructure
2533  * @field_name: a field in @structure
2534  * @target: the target value of the fixation
2535  *
2536  * Fixates a #GstStructure by changing the given @field_name field to the given
2537  * @target string if that field is not fixed yet.
2538  *
2539  * Returns: TRUE if the structure could be fixated
2540  *
2541  * Since: 0.10.30
2542  */
2543 gboolean
2544 gst_structure_fixate_field_string (GstStructure * structure,
2545     const gchar * field_name, const gchar * target)
2546 {
2547   const GValue *value;
2548
2549   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2550   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2551
2552   value = gst_structure_get_value (structure, field_name);
2553
2554   if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
2555     /* already fixed */
2556     return FALSE;
2557   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2558     const GValue *list_value;
2559     int i, n;
2560     const gchar *best = NULL;
2561     int best_index = -1;
2562
2563     n = gst_value_list_get_size (value);
2564     for (i = 0; i < n; i++) {
2565       list_value = gst_value_list_get_value (value, i);
2566       if (G_VALUE_TYPE (list_value) == G_TYPE_STRING) {
2567         const gchar *x = g_value_get_string (list_value);
2568
2569         if (best_index == -1 || g_str_equal (x, target)) {
2570           best_index = i;
2571           best = x;
2572         }
2573       }
2574     }
2575     if (best_index != -1) {
2576       gst_structure_set (structure, field_name, G_TYPE_STRING, best, NULL);
2577       return TRUE;
2578     }
2579     return FALSE;
2580   }
2581
2582   return FALSE;
2583 }
2584
2585 /**
2586  * gst_structure_fixate_field_nearest_fraction:
2587  * @structure: a #GstStructure
2588  * @field_name: a field in @structure
2589  * @target_numerator: The numerator of the target value of the fixation
2590  * @target_denominator: The denominator of the target value of the fixation
2591  *
2592  * Fixates a #GstStructure by changing the given field to the nearest
2593  * fraction to @target_numerator/@target_denominator that is a subset
2594  * of the existing field.
2595  *
2596  * Returns: TRUE if the structure could be fixated
2597  */
2598 gboolean
2599 gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
2600     const char *field_name, const gint target_numerator,
2601     const gint target_denominator)
2602 {
2603   const GValue *value;
2604
2605   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2606   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2607
2608   value = gst_structure_get_value (structure, field_name);
2609
2610   if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
2611     /* already fixed */
2612     return FALSE;
2613   } else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
2614     const GValue *x, *new_value;
2615     GValue target = { 0 };
2616     g_value_init (&target, GST_TYPE_FRACTION);
2617     gst_value_set_fraction (&target, target_numerator, target_denominator);
2618
2619     new_value = &target;
2620     x = gst_value_get_fraction_range_min (value);
2621     if (gst_value_compare (&target, x) == GST_VALUE_LESS_THAN)
2622       new_value = x;
2623     x = gst_value_get_fraction_range_max (value);
2624     if (gst_value_compare (&target, x) == GST_VALUE_GREATER_THAN)
2625       new_value = x;
2626
2627     gst_structure_set_value (structure, field_name, new_value);
2628     g_value_unset (&target);
2629     return TRUE;
2630   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2631     const GValue *list_value;
2632     int i, n;
2633     const GValue *best = NULL;
2634     gdouble target;
2635     gdouble cur_diff;
2636     gdouble best_diff = G_MAXDOUBLE;
2637
2638     target = (gdouble) target_numerator / (gdouble) target_denominator;
2639
2640     GST_DEBUG ("target %g, best %g", target, best_diff);
2641
2642     best = NULL;
2643
2644     n = gst_value_list_get_size (value);
2645     for (i = 0; i < n; i++) {
2646       list_value = gst_value_list_get_value (value, i);
2647       if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
2648         gint num, denom;
2649         gdouble list_double;
2650
2651         num = gst_value_get_fraction_numerator (list_value);
2652         denom = gst_value_get_fraction_denominator (list_value);
2653
2654         list_double = ((gdouble) num / (gdouble) denom);
2655         cur_diff = target - list_double;
2656
2657         GST_DEBUG ("curr diff %g, list %g", cur_diff, list_double);
2658
2659         if (cur_diff < 0)
2660           cur_diff = -cur_diff;
2661
2662         if (!best || cur_diff < best_diff) {
2663           GST_DEBUG ("new best %g", list_double);
2664           best = list_value;
2665           best_diff = cur_diff;
2666         }
2667       }
2668     }
2669     if (best != NULL) {
2670       gst_structure_set_value (structure, field_name, best);
2671       return TRUE;
2672     }
2673   }
2674
2675   return FALSE;
2676 }
2677
2678 static gboolean
2679 default_fixate (GQuark field_id, const GValue * value, gpointer data)
2680 {
2681   GstStructure *s = data;
2682   GValue v = { 0 };
2683
2684   if (gst_value_fixate (&v, value)) {
2685     gst_structure_id_set_value (s, field_id, &v);
2686     g_value_unset (&v);
2687   }
2688   return TRUE;
2689 }
2690
2691 /**
2692  * gst_structure_fixate_field:
2693  * @structure: a #GstStructure
2694  * @field_name: a field in @structure
2695  *
2696  * Fixates a #GstStructure by changing the given field with its fixated value.
2697  *
2698  * Returns: TRUE if the structure field could be fixated
2699  */
2700 gboolean
2701 gst_structure_fixate_field (GstStructure * structure, const char *field_name)
2702 {
2703   GstStructureField *field;
2704
2705   g_return_val_if_fail (structure != NULL, FALSE);
2706   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2707
2708   if (!(field = gst_structure_get_field (structure, field_name)))
2709     return FALSE;
2710
2711   return default_fixate (field->name, &field->value, structure);
2712 }
2713
2714 /* our very own version of G_VALUE_LCOPY that allows NULL return locations
2715  * (useful for message parsing functions where the return location is user
2716  * supplied and the user may pass NULL if the value isn't of interest) */
2717 #define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname)           \
2718 G_STMT_START {                                                                \
2719   const GValue *_value = (value);                                             \
2720   guint _flags = (flags);                                                     \
2721   GType _value_type = G_VALUE_TYPE (_value);                                  \
2722   GTypeValueTable *_vtable = g_type_value_table_peek (_value_type);           \
2723   gchar *_lcopy_format = _vtable->lcopy_format;                               \
2724   GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };      \
2725   guint _n_values = 0;                                                        \
2726                                                                               \
2727   while (*_lcopy_format != '\0') {                                            \
2728     g_assert (*_lcopy_format == G_VALUE_COLLECT_POINTER);                     \
2729     _cvalues[_n_values++].v_pointer = va_arg ((var_args), gpointer);          \
2730     _lcopy_format++;                                                          \
2731   }                                                                           \
2732   if (_n_values == 2 && !!_cvalues[0].v_pointer != !!_cvalues[1].v_pointer) { \
2733     *(__error) = g_strdup_printf ("either all or none of the return "         \
2734         "locations for field '%s' need to be NULL", fieldname);               \
2735   } else if (_cvalues[0].v_pointer != NULL) {                                 \
2736     *(__error) = _vtable->lcopy_value (_value, _n_values, _cvalues, _flags);  \
2737   }                                                                           \
2738 } G_STMT_END
2739
2740 /**
2741  * gst_structure_get_valist:
2742  * @structure: a #GstStructure
2743  * @first_fieldname: the name of the first field to read
2744  * @args: variable arguments
2745  *
2746  * Parses the variable arguments and reads fields from @structure accordingly.
2747  * valist-variant of gst_structure_get(). Look at the documentation of
2748  * gst_structure_get() for more details.
2749  *
2750  * Returns: TRUE, or FALSE if there was a problem reading any of the fields
2751  *
2752  * Since: 0.10.24
2753  */
2754 gboolean
2755 gst_structure_get_valist (const GstStructure * structure,
2756     const char *first_fieldname, va_list args)
2757 {
2758   const char *field_name;
2759   GType expected_type = G_TYPE_INVALID;
2760
2761   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2762   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2763
2764   field_name = first_fieldname;
2765   while (field_name) {
2766     const GValue *val = NULL;
2767     gchar *err = NULL;
2768
2769     expected_type = va_arg (args, GType);
2770
2771     val = gst_structure_get_value (structure, field_name);
2772
2773     if (val == NULL)
2774       goto no_such_field;
2775
2776     if (G_VALUE_TYPE (val) != expected_type)
2777       goto wrong_type;
2778
2779     GST_VALUE_LCOPY (val, args, 0, &err, field_name);
2780     if (err) {
2781       g_warning ("%s: %s", G_STRFUNC, err);
2782       g_free (err);
2783       return FALSE;
2784     }
2785
2786     field_name = va_arg (args, const gchar *);
2787   }
2788
2789   return TRUE;
2790
2791 /* ERRORS */
2792 no_such_field:
2793   {
2794     GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2795         field_name, structure);
2796     return FALSE;
2797   }
2798 wrong_type:
2799   {
2800     GST_WARNING ("Expected field '%s' in structure to be of type '%s', but "
2801         "field was of type '%s': %" GST_PTR_FORMAT, field_name,
2802         GST_STR_NULL (g_type_name (expected_type)),
2803         G_VALUE_TYPE_NAME (gst_structure_get_value (structure, field_name)),
2804         structure);
2805     return FALSE;
2806   }
2807 }
2808
2809 /**
2810  * gst_structure_id_get_valist:
2811  * @structure: a #GstStructure
2812  * @first_field_id: the quark of the first field to read
2813  * @args: variable arguments
2814  *
2815  * Parses the variable arguments and reads fields from @structure accordingly.
2816  * valist-variant of gst_structure_id_get(). Look at the documentation of
2817  * gst_structure_id_get() for more details.
2818  *
2819  * Returns: TRUE, or FALSE if there was a problem reading any of the fields
2820  *
2821  * Since: 0.10.24
2822  */
2823 gboolean
2824 gst_structure_id_get_valist (const GstStructure * structure,
2825     GQuark first_field_id, va_list args)
2826 {
2827   GQuark field_id;
2828   GType expected_type = G_TYPE_INVALID;
2829
2830   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2831   g_return_val_if_fail (first_field_id != 0, FALSE);
2832
2833   field_id = first_field_id;
2834   while (field_id) {
2835     const GValue *val = NULL;
2836     gchar *err = NULL;
2837
2838     expected_type = va_arg (args, GType);
2839
2840     val = gst_structure_id_get_value (structure, field_id);
2841
2842     if (val == NULL)
2843       goto no_such_field;
2844
2845     if (G_VALUE_TYPE (val) != expected_type)
2846       goto wrong_type;
2847
2848     GST_VALUE_LCOPY (val, args, 0, &err, g_quark_to_string (field_id));
2849     if (err) {
2850       g_warning ("%s: %s", G_STRFUNC, err);
2851       g_free (err);
2852       return FALSE;
2853     }
2854
2855     field_id = va_arg (args, GQuark);
2856   }
2857
2858   return TRUE;
2859
2860 /* ERRORS */
2861 no_such_field:
2862   {
2863     GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2864         GST_STR_NULL (g_quark_to_string (field_id)), structure);
2865     return FALSE;
2866   }
2867 wrong_type:
2868   {
2869     GST_WARNING ("Expected field '%s' in structure to be of type '%s', but "
2870         "field was of type '%s': %" GST_PTR_FORMAT,
2871         g_quark_to_string (field_id),
2872         GST_STR_NULL (g_type_name (expected_type)),
2873         G_VALUE_TYPE_NAME (gst_structure_id_get_value (structure, field_id)),
2874         structure);
2875     return FALSE;
2876   }
2877 }
2878
2879 /**
2880  * gst_structure_get:
2881  * @structure: a #GstStructure
2882  * @first_fieldname: the name of the first field to read
2883  * @...: variable arguments
2884  *
2885  * Parses the variable arguments and reads fields from @structure accordingly.
2886  * Variable arguments should be in the form field name, field type
2887  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2888  * The last variable argument should be NULL.
2889  *
2890  * For refcounted (mini)objects you will receive a new reference which
2891  * you must release with a suitable _unref() when no longer needed. For
2892  * strings and boxed types you will receive a copy which you will need to
2893  * release with either g_free() or the suitable function for the boxed type.
2894  *
2895  * Returns: FALSE if there was a problem reading any of the fields (e.g.
2896  *     because the field requested did not exist, or was of a type other
2897  *     than the type specified), otherwise TRUE.
2898  *
2899  * Since: 0.10.24
2900  */
2901 gboolean
2902 gst_structure_get (const GstStructure * structure, const char *first_fieldname,
2903     ...)
2904 {
2905   gboolean ret;
2906   va_list args;
2907
2908   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2909   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2910
2911   va_start (args, first_fieldname);
2912   ret = gst_structure_get_valist (structure, first_fieldname, args);
2913   va_end (args);
2914
2915   return ret;
2916 }
2917
2918 /**
2919  * gst_structure_id_get:
2920  * @structure: a #GstStructure
2921  * @first_field_id: the quark of the first field to read
2922  * @...: variable arguments
2923  *
2924  * Parses the variable arguments and reads fields from @structure accordingly.
2925  * Variable arguments should be in the form field id quark, field type
2926  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2927  * The last variable argument should be NULL (technically it should be a
2928  * 0 quark, but we require NULL so compilers that support it can check for
2929  * the NULL terminator and warn if it's not there).
2930  *
2931  * This function is just like gst_structure_get() only that it is slightly
2932  * more efficient since it saves the string-to-quark lookup in the global
2933  * quark hashtable.
2934  *
2935  * For refcounted (mini)objects you will receive a new reference which
2936  * you must release with a suitable _unref() when no longer needed. For
2937  * strings and boxed types you will receive a copy which you will need to
2938  * release with either g_free() or the suitable function for the boxed type.
2939  *
2940  * Returns: FALSE if there was a problem reading any of the fields (e.g.
2941  *     because the field requested did not exist, or was of a type other
2942  *     than the type specified), otherwise TRUE.
2943  *
2944  * Since: 0.10.24
2945  */
2946 gboolean
2947 gst_structure_id_get (const GstStructure * structure, GQuark first_field_id,
2948     ...)
2949 {
2950   gboolean ret;
2951   va_list args;
2952
2953   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2954   g_return_val_if_fail (first_field_id != 0, FALSE);
2955
2956   va_start (args, first_field_id);
2957   ret = gst_structure_id_get_valist (structure, first_field_id, args);
2958   va_end (args);
2959
2960   return ret;
2961 }
2962
2963 static gboolean
2964 gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
2965     gpointer data)
2966 {
2967   const GstStructure *struct1 = (const GstStructure *) data;
2968   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
2969
2970   if (G_UNLIKELY (val1 == NULL))
2971     return FALSE;
2972   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
2973     return TRUE;
2974   }
2975
2976   return FALSE;
2977 }
2978
2979 /**
2980  * gst_structure_is_equal:
2981  * @structure1: a #GstStructure.
2982  * @structure2: a #GstStructure.
2983  *
2984  * Tests if the two #GstStructure are equal.
2985  *
2986  * Returns: TRUE if the two structures have the same name and field.
2987  *
2988  * Since: 0.10.36
2989  **/
2990 gboolean
2991 gst_structure_is_equal (const GstStructure * structure1,
2992     const GstStructure * structure2)
2993 {
2994   g_return_val_if_fail (GST_IS_STRUCTURE (structure1), FALSE);
2995   g_return_val_if_fail (GST_IS_STRUCTURE (structure2), FALSE);
2996
2997   if (G_UNLIKELY (structure1 == structure2))
2998     return TRUE;
2999
3000   if (structure1->name != structure2->name) {
3001     return FALSE;
3002   }
3003   if (GST_STRUCTURE_FIELDS (structure1)->len !=
3004       GST_STRUCTURE_FIELDS (structure2)->len) {
3005     return FALSE;
3006   }
3007
3008   return gst_structure_foreach (structure1, gst_structure_is_equal_foreach,
3009       (gpointer) structure2);
3010 }
3011
3012
3013 typedef struct
3014 {
3015   GstStructure *dest;
3016   const GstStructure *intersect;
3017 }
3018 IntersectData;
3019
3020 static gboolean
3021 gst_structure_intersect_field1 (GQuark id, const GValue * val1, gpointer data)
3022 {
3023   IntersectData *idata = (IntersectData *) data;
3024   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
3025
3026   if (G_UNLIKELY (val2 == NULL)) {
3027     gst_structure_id_set_value (idata->dest, id, val1);
3028   } else {
3029     GValue dest_value = { 0 };
3030     if (gst_value_intersect (&dest_value, val1, val2)) {
3031       gst_structure_id_set_value (idata->dest, id, &dest_value);
3032       g_value_unset (&dest_value);
3033     } else {
3034       return FALSE;
3035     }
3036   }
3037   return TRUE;
3038 }
3039
3040 static gboolean
3041 gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
3042 {
3043   IntersectData *idata = (IntersectData *) data;
3044   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
3045
3046   if (G_UNLIKELY (val2 == NULL)) {
3047     gst_structure_id_set_value (idata->dest, id, val1);
3048   }
3049   return TRUE;
3050 }
3051
3052 /**
3053  * gst_structure_intersect:
3054  * @struct1: a #GstStructure
3055  * @struct2: a #GstStructure
3056  *
3057  * Interesects @struct1 and @struct2 and returns the intersection.
3058  *
3059  * Returns: Intersection of @struct1 and @struct2
3060  *
3061  * Since: 0.10.36
3062  */
3063 GstStructure *
3064 gst_structure_intersect (const GstStructure * struct1,
3065     const GstStructure * struct2)
3066 {
3067   IntersectData data;
3068
3069   g_assert (struct1 != NULL);
3070   g_assert (struct2 != NULL);
3071
3072   if (G_UNLIKELY (struct1->name != struct2->name))
3073     return NULL;
3074
3075   /* copy fields from struct1 which we have not in struct2 to target
3076    * intersect if we have the field in both */
3077   data.dest = gst_structure_new_id_empty (struct1->name);
3078   data.intersect = struct2;
3079   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
3080               gst_structure_intersect_field1, &data)))
3081     goto error;
3082
3083   /* copy fields from struct2 which we have not in struct1 to target */
3084   data.intersect = struct1;
3085   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
3086               gst_structure_intersect_field2, &data)))
3087     goto error;
3088
3089   return data.dest;
3090
3091 error:
3092   gst_structure_free (data.dest);
3093   return NULL;
3094 }
3095
3096 static gboolean
3097 gst_caps_structure_can_intersect_field (GQuark id, const GValue * val1,
3098     gpointer data)
3099 {
3100   GstStructure *other = (GstStructure *) data;
3101   const GValue *val2 = gst_structure_id_get_value (other, id);
3102
3103   if (G_LIKELY (val2)) {
3104     if (!gst_value_can_intersect (val1, val2)) {
3105       return FALSE;
3106     } else {
3107       gint eq = gst_value_compare (val1, val2);
3108
3109       if (eq == GST_VALUE_UNORDERED) {
3110         /* we need to try interseting */
3111         if (!gst_value_intersect (NULL, val1, val2)) {
3112           return FALSE;
3113         }
3114       } else if (eq != GST_VALUE_EQUAL) {
3115         return FALSE;
3116       }
3117     }
3118   }
3119   return TRUE;
3120 }
3121
3122 /**
3123  * gst_structure_can_intersect:
3124  * @struct1: a #GstStructure
3125  * @struct2: a #GstStructure
3126  *
3127  * Tries intersecting @struct1 and @struct2 and reports whether the result
3128  * would not be empty.
3129  *
3130  * Returns: %TRUE if intersection would not be empty
3131  *
3132  * Since: 0.10.36
3133  */
3134 gboolean
3135 gst_structure_can_intersect (const GstStructure * struct1,
3136     const GstStructure * struct2)
3137 {
3138   g_return_val_if_fail (GST_IS_STRUCTURE (struct1), FALSE);
3139   g_return_val_if_fail (GST_IS_STRUCTURE (struct2), FALSE);
3140
3141   if (G_UNLIKELY (struct1->name != struct2->name))
3142     return FALSE;
3143
3144   /* tries to intersect if we have the field in both */
3145   return gst_structure_foreach ((GstStructure *) struct1,
3146       gst_caps_structure_can_intersect_field, (gpointer) struct2);
3147 }
3148
3149 static gboolean
3150 gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
3151     gpointer user_data)
3152 {
3153   GstStructure *superset = user_data;
3154   const GValue *other;
3155   int comparison;
3156
3157   if (!(other = gst_structure_id_get_value (superset, field_id)))
3158     /* field is missing in the superset => is subset */
3159     return TRUE;
3160
3161   comparison = gst_value_compare (other, value);
3162
3163   /* equal values are subset */
3164   if (comparison == GST_VALUE_EQUAL)
3165     return TRUE;
3166
3167   /* ordered, but unequal, values are not */
3168   if (comparison != GST_VALUE_UNORDERED)
3169     return FALSE;
3170
3171   return gst_value_is_subset (value, other);
3172 }
3173
3174 /**
3175  * gst_structure_is_subset:
3176  * @subset: a #GstStructure
3177  * @superset: a potentially greater #GstStructure
3178  *
3179  * Checks if @subset is a subset of @superset, i.e. has the same
3180  * structure name and for all fields that are existing in @superset,
3181  * @subset has a value that is a subset of the value in @superset.
3182  *
3183  * Returns: %TRUE if @subset is a subset of @superset
3184  *
3185  * Since: 0.10.36
3186  */
3187 gboolean
3188 gst_structure_is_subset (const GstStructure * subset,
3189     const GstStructure * superset)
3190 {
3191   if ((superset->name != subset->name) ||
3192       (gst_structure_n_fields (superset) > gst_structure_n_fields (subset)))
3193     return FALSE;
3194
3195   return gst_structure_foreach ((GstStructure *) subset,
3196       gst_caps_structure_is_subset_field, (gpointer) superset);
3197 }
3198
3199
3200 /**
3201  * gst_structure_fixate:
3202  * @structure: a #GstStructure
3203  *
3204  * Fixate all values in @structure using gst_value_fixate().
3205  * @structure will be modified in-place and should be writable.
3206  */
3207 void
3208 gst_structure_fixate (GstStructure * structure)
3209 {
3210   g_return_if_fail (GST_IS_STRUCTURE (structure));
3211
3212   gst_structure_foreach (structure, default_fixate, structure);
3213 }