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