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