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