gst: Fix up a bunch of GIR annotations
[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: (nullable): the #GValue corresponding to the field with the given
883  * name.
884  */
885 const GValue *
886 gst_structure_get_value (const GstStructure * structure,
887     const gchar * fieldname)
888 {
889   GstStructureField *field;
890
891   g_return_val_if_fail (structure != NULL, NULL);
892   g_return_val_if_fail (fieldname != NULL, NULL);
893
894   field = gst_structure_get_field (structure, fieldname);
895   if (field == NULL)
896     return NULL;
897
898   return &field->value;
899 }
900
901 /**
902  * gst_structure_id_get_value:
903  * @structure: a #GstStructure
904  * @field: the #GQuark of the field to get
905  *
906  * Get the value of the field with GQuark @field.
907  *
908  * Returns: (nullable): the #GValue corresponding to the field with the given
909  * name identifier.
910  */
911 const GValue *
912 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
913 {
914   GstStructureField *gsfield;
915
916   g_return_val_if_fail (structure != NULL, NULL);
917
918   gsfield = gst_structure_id_get_field (structure, field);
919   if (gsfield == NULL)
920     return NULL;
921
922   return &gsfield->value;
923 }
924
925 /**
926  * gst_structure_remove_field:
927  * @structure: a #GstStructure
928  * @fieldname: the name of the field to remove
929  *
930  * Removes the field with the given name.  If the field with the given
931  * name does not exist, the structure is unchanged.
932  */
933 void
934 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
935 {
936   GstStructureField *field;
937   GQuark id;
938   guint i, len;
939
940   g_return_if_fail (structure != NULL);
941   g_return_if_fail (fieldname != NULL);
942   g_return_if_fail (IS_MUTABLE (structure));
943
944   id = g_quark_from_string (fieldname);
945   len = GST_STRUCTURE_FIELDS (structure)->len;
946
947   for (i = 0; i < len; i++) {
948     field = GST_STRUCTURE_FIELD (structure, i);
949
950     if (field->name == id) {
951       if (G_IS_VALUE (&field->value)) {
952         g_value_unset (&field->value);
953       }
954       GST_STRUCTURE_FIELDS (structure) =
955           g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
956       return;
957     }
958   }
959 }
960
961 /**
962  * gst_structure_remove_fields:
963  * @structure: a #GstStructure
964  * @fieldname: the name of the field to remove
965  * @...: %NULL-terminated list of more fieldnames to remove
966  *
967  * Removes the fields with the given names. If a field does not exist, the
968  * argument is ignored.
969  */
970 void
971 gst_structure_remove_fields (GstStructure * structure,
972     const gchar * fieldname, ...)
973 {
974   va_list varargs;
975
976   g_return_if_fail (structure != NULL);
977   g_return_if_fail (fieldname != NULL);
978   /* mutability checked in remove_field */
979
980   va_start (varargs, fieldname);
981   gst_structure_remove_fields_valist (structure, fieldname, varargs);
982   va_end (varargs);
983 }
984
985 /**
986  * gst_structure_remove_fields_valist:
987  * @structure: a #GstStructure
988  * @fieldname: the name of the field to remove
989  * @varargs: %NULL-terminated list of more fieldnames to remove
990  *
991  * va_list form of gst_structure_remove_fields().
992  */
993 void
994 gst_structure_remove_fields_valist (GstStructure * structure,
995     const gchar * fieldname, va_list varargs)
996 {
997   gchar *field = (gchar *) fieldname;
998
999   g_return_if_fail (structure != NULL);
1000   g_return_if_fail (fieldname != NULL);
1001   /* mutability checked in remove_field */
1002
1003   while (field) {
1004     gst_structure_remove_field (structure, field);
1005     field = va_arg (varargs, char *);
1006   }
1007 }
1008
1009 /**
1010  * gst_structure_remove_all_fields:
1011  * @structure: a #GstStructure
1012  *
1013  * Removes all fields in a GstStructure.
1014  */
1015 void
1016 gst_structure_remove_all_fields (GstStructure * structure)
1017 {
1018   GstStructureField *field;
1019   int i;
1020
1021   g_return_if_fail (structure != NULL);
1022   g_return_if_fail (IS_MUTABLE (structure));
1023
1024   for (i = GST_STRUCTURE_FIELDS (structure)->len - 1; i >= 0; i--) {
1025     field = GST_STRUCTURE_FIELD (structure, i);
1026
1027     if (G_IS_VALUE (&field->value)) {
1028       g_value_unset (&field->value);
1029     }
1030     GST_STRUCTURE_FIELDS (structure) =
1031         g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
1032   }
1033 }
1034
1035 /**
1036  * gst_structure_get_field_type:
1037  * @structure: a #GstStructure
1038  * @fieldname: the name of the field
1039  *
1040  * Finds the field with the given name, and returns the type of the
1041  * value it contains.  If the field is not found, G_TYPE_INVALID is
1042  * returned.
1043  *
1044  * Returns: the #GValue of the field
1045  */
1046 GType
1047 gst_structure_get_field_type (const GstStructure * structure,
1048     const gchar * fieldname)
1049 {
1050   GstStructureField *field;
1051
1052   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
1053   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
1054
1055   field = gst_structure_get_field (structure, fieldname);
1056   if (field == NULL)
1057     return G_TYPE_INVALID;
1058
1059   return G_VALUE_TYPE (&field->value);
1060 }
1061
1062 /**
1063  * gst_structure_n_fields:
1064  * @structure: a #GstStructure
1065  *
1066  * Get the number of fields in the structure.
1067  *
1068  * Returns: the number of fields in the structure
1069  */
1070 gint
1071 gst_structure_n_fields (const GstStructure * structure)
1072 {
1073   g_return_val_if_fail (structure != NULL, 0);
1074
1075   return GST_STRUCTURE_FIELDS (structure)->len;
1076 }
1077
1078 /**
1079  * gst_structure_nth_field_name:
1080  * @structure: a #GstStructure
1081  * @index: the index to get the name of
1082  *
1083  * Get the name of the given field number, counting from 0 onwards.
1084  *
1085  * Returns: the name of the given field number
1086  */
1087 const gchar *
1088 gst_structure_nth_field_name (const GstStructure * structure, guint index)
1089 {
1090   GstStructureField *field;
1091
1092   g_return_val_if_fail (structure != NULL, NULL);
1093   g_return_val_if_fail (index < GST_STRUCTURE_FIELDS (structure)->len, NULL);
1094
1095   field = GST_STRUCTURE_FIELD (structure, index);
1096
1097   return g_quark_to_string (field->name);
1098 }
1099
1100 /**
1101  * gst_structure_foreach:
1102  * @structure: a #GstStructure
1103  * @func: (scope call): a function to call for each field
1104  * @user_data: (closure): private data
1105  *
1106  * Calls the provided function once for each field in the #GstStructure. The
1107  * function must not modify the fields. Also see gst_structure_map_in_place()
1108  * and gst_structure_filter_and_map_in_place().
1109  *
1110  * Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
1111  * %FALSE otherwise.
1112  */
1113 gboolean
1114 gst_structure_foreach (const GstStructure * structure,
1115     GstStructureForeachFunc func, gpointer user_data)
1116 {
1117   guint i, len;
1118   GstStructureField *field;
1119   gboolean ret;
1120
1121   g_return_val_if_fail (structure != NULL, FALSE);
1122   g_return_val_if_fail (func != NULL, FALSE);
1123
1124   len = GST_STRUCTURE_FIELDS (structure)->len;
1125
1126   for (i = 0; i < len; i++) {
1127     field = GST_STRUCTURE_FIELD (structure, i);
1128
1129     ret = func (field->name, &field->value, user_data);
1130     if (G_UNLIKELY (!ret))
1131       return FALSE;
1132   }
1133
1134   return TRUE;
1135 }
1136
1137 /**
1138  * gst_structure_map_in_place:
1139  * @structure: a #GstStructure
1140  * @func: (scope call): a function to call for each field
1141  * @user_data: (closure): private data
1142  *
1143  * Calls the provided function once for each field in the #GstStructure. In
1144  * contrast to gst_structure_foreach(), the function may modify but not delete the
1145  * fields. The structure must be mutable.
1146  *
1147  * Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
1148  * %FALSE otherwise.
1149  */
1150 gboolean
1151 gst_structure_map_in_place (GstStructure * structure,
1152     GstStructureMapFunc func, gpointer user_data)
1153 {
1154   guint i, len;
1155   GstStructureField *field;
1156   gboolean ret;
1157
1158   g_return_val_if_fail (structure != NULL, FALSE);
1159   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1160   g_return_val_if_fail (func != NULL, FALSE);
1161   len = GST_STRUCTURE_FIELDS (structure)->len;
1162
1163   for (i = 0; i < len; i++) {
1164     field = GST_STRUCTURE_FIELD (structure, i);
1165
1166     ret = func (field->name, &field->value, user_data);
1167     if (!ret)
1168       return FALSE;
1169   }
1170
1171   return TRUE;
1172 }
1173
1174 /**
1175  * gst_structure_filter_and_map_in_place:
1176  * @structure: a #GstStructure
1177  * @func: (scope call): a function to call for each field
1178  * @user_data: (closure): private data
1179  *
1180  * Calls the provided function once for each field in the #GstStructure. In
1181  * contrast to gst_structure_foreach(), the function may modify the fields.
1182  * In contrast to gst_structure_map_in_place(), the field is removed from
1183  * the structure if %FALSE is returned from the function.
1184  * The structure must be mutable.
1185  *
1186  * Since: 1.6
1187  */
1188 void
1189 gst_structure_filter_and_map_in_place (GstStructure * structure,
1190     GstStructureFilterMapFunc func, gpointer user_data)
1191 {
1192   guint i, len;
1193   GstStructureField *field;
1194   gboolean ret;
1195
1196   g_return_if_fail (structure != NULL);
1197   g_return_if_fail (IS_MUTABLE (structure));
1198   g_return_if_fail (func != NULL);
1199   len = GST_STRUCTURE_FIELDS (structure)->len;
1200
1201   for (i = 0; i < len;) {
1202     field = GST_STRUCTURE_FIELD (structure, i);
1203
1204     ret = func (field->name, &field->value, user_data);
1205
1206     if (!ret) {
1207       if (G_IS_VALUE (&field->value)) {
1208         g_value_unset (&field->value);
1209       }
1210       GST_STRUCTURE_FIELDS (structure) =
1211           g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
1212       len = GST_STRUCTURE_FIELDS (structure)->len;
1213     } else {
1214       i++;
1215     }
1216   }
1217 }
1218
1219 /**
1220  * gst_structure_id_has_field:
1221  * @structure: a #GstStructure
1222  * @field: #GQuark of the field name
1223  *
1224  * Check if @structure contains a field named @field.
1225  *
1226  * Returns: %TRUE if the structure contains a field with the given name
1227  */
1228 gboolean
1229 gst_structure_id_has_field (const GstStructure * structure, GQuark field)
1230 {
1231   GstStructureField *f;
1232
1233   g_return_val_if_fail (structure != NULL, FALSE);
1234   g_return_val_if_fail (field != 0, FALSE);
1235
1236   f = gst_structure_id_get_field (structure, field);
1237
1238   return (f != NULL);
1239 }
1240
1241 /**
1242  * gst_structure_has_field:
1243  * @structure: a #GstStructure
1244  * @fieldname: the name of a field
1245  *
1246  * Check if @structure contains a field named @fieldname.
1247  *
1248  * Returns: %TRUE if the structure contains a field with the given name
1249  */
1250 gboolean
1251 gst_structure_has_field (const GstStructure * structure,
1252     const gchar * fieldname)
1253 {
1254   g_return_val_if_fail (structure != NULL, FALSE);
1255   g_return_val_if_fail (fieldname != NULL, FALSE);
1256
1257   return gst_structure_id_has_field (structure,
1258       g_quark_from_string (fieldname));
1259 }
1260
1261 /**
1262  * gst_structure_id_has_field_typed:
1263  * @structure: a #GstStructure
1264  * @field: #GQuark of the field name
1265  * @type: the type of a value
1266  *
1267  * Check if @structure contains a field named @field and with GType @type.
1268  *
1269  * Returns: %TRUE if the structure contains a field with the given name and type
1270  */
1271 gboolean
1272 gst_structure_id_has_field_typed (const GstStructure * structure,
1273     GQuark field, GType type)
1274 {
1275   GstStructureField *f;
1276
1277   g_return_val_if_fail (structure != NULL, FALSE);
1278   g_return_val_if_fail (field != 0, FALSE);
1279
1280   f = gst_structure_id_get_field (structure, field);
1281   if (f == NULL)
1282     return FALSE;
1283
1284   return (G_VALUE_TYPE (&f->value) == type);
1285 }
1286
1287 /**
1288  * gst_structure_has_field_typed:
1289  * @structure: a #GstStructure
1290  * @fieldname: the name of a field
1291  * @type: the type of a value
1292  *
1293  * Check if @structure contains a field named @fieldname and with GType @type.
1294  *
1295  * Returns: %TRUE if the structure contains a field with the given name and type
1296  */
1297 gboolean
1298 gst_structure_has_field_typed (const GstStructure * structure,
1299     const gchar * fieldname, GType type)
1300 {
1301   g_return_val_if_fail (structure != NULL, FALSE);
1302   g_return_val_if_fail (fieldname != NULL, FALSE);
1303
1304   return gst_structure_id_has_field_typed (structure,
1305       g_quark_from_string (fieldname), type);
1306 }
1307
1308 /* utility functions */
1309
1310 /**
1311  * gst_structure_get_boolean:
1312  * @structure: a #GstStructure
1313  * @fieldname: the name of a field
1314  * @value: (out): a pointer to a #gboolean to set
1315  *
1316  * Sets the boolean pointed to by @value corresponding to the value of the
1317  * given field.  Caller is responsible for making sure the field exists
1318  * and has the correct type.
1319  *
1320  * Returns: %TRUE if the value could be set correctly. If there was no field
1321  * with @fieldname or the existing field did not contain a boolean, this
1322  * function returns %FALSE.
1323  */
1324 gboolean
1325 gst_structure_get_boolean (const GstStructure * structure,
1326     const gchar * fieldname, gboolean * value)
1327 {
1328   GstStructureField *field;
1329
1330   g_return_val_if_fail (structure != NULL, FALSE);
1331   g_return_val_if_fail (fieldname != NULL, FALSE);
1332
1333   field = gst_structure_get_field (structure, fieldname);
1334
1335   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_BOOLEAN)
1336     return FALSE;
1337
1338   *value = gst_g_value_get_boolean_unchecked (&field->value);
1339
1340   return TRUE;
1341 }
1342
1343 /**
1344  * gst_structure_get_int:
1345  * @structure: a #GstStructure
1346  * @fieldname: the name of a field
1347  * @value: (out): a pointer to an int to set
1348  *
1349  * Sets the int pointed to by @value corresponding to the value of the
1350  * given field.  Caller is responsible for making sure the field exists
1351  * and has the correct type.
1352  *
1353  * Returns: %TRUE if the value could be set correctly. If there was no field
1354  * with @fieldname or the existing field did not contain an int, this function
1355  * returns %FALSE.
1356  */
1357 gboolean
1358 gst_structure_get_int (const GstStructure * structure,
1359     const gchar * fieldname, gint * value)
1360 {
1361   GstStructureField *field;
1362
1363   g_return_val_if_fail (structure != NULL, FALSE);
1364   g_return_val_if_fail (fieldname != NULL, FALSE);
1365   g_return_val_if_fail (value != NULL, FALSE);
1366
1367   field = gst_structure_get_field (structure, fieldname);
1368
1369   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT)
1370     return FALSE;
1371
1372   *value = gst_g_value_get_int_unchecked (&field->value);
1373
1374   return TRUE;
1375 }
1376
1377 /**
1378  * gst_structure_get_uint:
1379  * @structure: a #GstStructure
1380  * @fieldname: the name of a field
1381  * @value: (out): a pointer to a uint to set
1382  *
1383  * Sets the uint pointed to by @value corresponding to the value of the
1384  * given field.  Caller is responsible for making sure the field exists
1385  * and has the correct type.
1386  *
1387  * Returns: %TRUE if the value could be set correctly. If there was no field
1388  * with @fieldname or the existing field did not contain a uint, this function
1389  * returns %FALSE.
1390  */
1391 gboolean
1392 gst_structure_get_uint (const GstStructure * structure,
1393     const gchar * fieldname, guint * value)
1394 {
1395   GstStructureField *field;
1396
1397   g_return_val_if_fail (structure != NULL, FALSE);
1398   g_return_val_if_fail (fieldname != NULL, FALSE);
1399   g_return_val_if_fail (value != NULL, FALSE);
1400
1401   field = gst_structure_get_field (structure, fieldname);
1402
1403   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT)
1404     return FALSE;
1405
1406   *value = gst_g_value_get_uint_unchecked (&field->value);
1407
1408   return TRUE;
1409 }
1410
1411 /**
1412  * gst_structure_get_int64:
1413  * @structure: a #GstStructure
1414  * @fieldname: the name of a field
1415  * @value: (out): a pointer to a #gint64 to set
1416  *
1417  * Sets the #gint64 pointed to by @value corresponding to the value of the
1418  * given field. Caller is responsible for making sure the field exists
1419  * and has the correct type.
1420  *
1421  * Returns: %TRUE if the value could be set correctly. If there was no field
1422  * with @fieldname or the existing field did not contain a #gint64, this function
1423  * returns %FALSE.
1424  *
1425  * Since: 1.4
1426  */
1427 gboolean
1428 gst_structure_get_int64 (const GstStructure * structure,
1429     const gchar * fieldname, gint64 * value)
1430 {
1431   GstStructureField *field;
1432
1433   g_return_val_if_fail (structure != NULL, FALSE);
1434   g_return_val_if_fail (fieldname != NULL, FALSE);
1435   g_return_val_if_fail (value != NULL, FALSE);
1436
1437   field = gst_structure_get_field (structure, fieldname);
1438
1439   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT64)
1440     return FALSE;
1441
1442   *value = gst_g_value_get_int64_unchecked (&field->value);
1443
1444   return TRUE;
1445 }
1446
1447 /**
1448  * gst_structure_get_uint64:
1449  * @structure: a #GstStructure
1450  * @fieldname: the name of a field
1451  * @value: (out): a pointer to a #guint64 to set
1452  *
1453  * Sets the #guint64 pointed to by @value corresponding to the value of the
1454  * given field. Caller is responsible for making sure the field exists
1455  * and has the correct type.
1456  *
1457  * Returns: %TRUE if the value could be set correctly. If there was no field
1458  * with @fieldname or the existing field did not contain a #guint64, this function
1459  * returns %FALSE.
1460  *
1461  * Since: 1.4
1462  */
1463 gboolean
1464 gst_structure_get_uint64 (const GstStructure * structure,
1465     const gchar * fieldname, guint64 * value)
1466 {
1467   GstStructureField *field;
1468
1469   g_return_val_if_fail (structure != NULL, FALSE);
1470   g_return_val_if_fail (fieldname != NULL, FALSE);
1471   g_return_val_if_fail (value != NULL, FALSE);
1472
1473   field = gst_structure_get_field (structure, fieldname);
1474
1475   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT64)
1476     return FALSE;
1477
1478   *value = gst_g_value_get_uint64_unchecked (&field->value);
1479
1480   return TRUE;
1481 }
1482
1483 /**
1484  * gst_structure_get_date:
1485  * @structure: a #GstStructure
1486  * @fieldname: the name of a field
1487  * @value: (out callee-allocates): a pointer to a #GDate to set
1488  *
1489  * Sets the date pointed to by @value corresponding to the date of the
1490  * given field.  Caller is responsible for making sure the field exists
1491  * and has the correct type.
1492  *
1493  * On success @value will point to a newly-allocated copy of the date which
1494  * should be freed with g_date_free() when no longer needed (note: this is
1495  * inconsistent with e.g. gst_structure_get_string() which doesn't return a
1496  * copy of the string).
1497  *
1498  * Returns: %TRUE if the value could be set correctly. If there was no field
1499  * with @fieldname or the existing field did not contain a data, this function
1500  * returns %FALSE.
1501  */
1502 gboolean
1503 gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
1504     GDate ** value)
1505 {
1506   GstStructureField *field;
1507
1508   g_return_val_if_fail (structure != NULL, FALSE);
1509   g_return_val_if_fail (fieldname != NULL, FALSE);
1510   g_return_val_if_fail (value != NULL, FALSE);
1511
1512   field = gst_structure_get_field (structure, fieldname);
1513
1514   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DATE)
1515     return FALSE;
1516
1517   /* FIXME: 2.0 g_value_dup_boxed() -> g_value_get_boxed() */
1518   *value = g_value_dup_boxed (&field->value);
1519
1520   return TRUE;
1521 }
1522
1523 /**
1524  * gst_structure_get_date_time:
1525  * @structure: a #GstStructure
1526  * @fieldname: the name of a field
1527  * @value: (out callee-allocates): a pointer to a #GstDateTime to set
1528  *
1529  * Sets the datetime pointed to by @value corresponding to the datetime of the
1530  * given field. Caller is responsible for making sure the field exists
1531  * and has the correct type.
1532  *
1533  * On success @value will point to a reference of the datetime which
1534  * should be unreffed with gst_date_time_unref() when no longer needed
1535  * (note: this is inconsistent with e.g. gst_structure_get_string()
1536  * which doesn't return a copy of the string).
1537  *
1538  * Returns: %TRUE if the value could be set correctly. If there was no field
1539  * with @fieldname or the existing field did not contain a data, this function
1540  * returns %FALSE.
1541  */
1542 gboolean
1543 gst_structure_get_date_time (const GstStructure * structure,
1544     const gchar * fieldname, GstDateTime ** value)
1545 {
1546   GstStructureField *field;
1547
1548   g_return_val_if_fail (structure != NULL, FALSE);
1549   g_return_val_if_fail (fieldname != NULL, FALSE);
1550   g_return_val_if_fail (value != NULL, FALSE);
1551
1552   field = gst_structure_get_field (structure, fieldname);
1553
1554   if (field == NULL)
1555     return FALSE;
1556   if (!GST_VALUE_HOLDS_DATE_TIME (&field->value))
1557     return FALSE;
1558
1559   /* FIXME 2.0: g_value_dup_boxed() -> g_value_get_boxed() */
1560   *value = g_value_dup_boxed (&field->value);
1561
1562   return TRUE;
1563 }
1564
1565 /**
1566  * gst_structure_get_clock_time:
1567  * @structure: a #GstStructure
1568  * @fieldname: the name of a field
1569  * @value: (out): a pointer to a #GstClockTime to set
1570  *
1571  * Sets the clock time pointed to by @value corresponding to the clock time
1572  * of the given field.  Caller is responsible for making sure the field exists
1573  * and has the correct type.
1574  *
1575  * Returns: %TRUE if the value could be set correctly. If there was no field
1576  * with @fieldname or the existing field did not contain a #GstClockTime, this
1577  * function returns %FALSE.
1578  */
1579 gboolean
1580 gst_structure_get_clock_time (const GstStructure * structure,
1581     const gchar * fieldname, GstClockTime * value)
1582 {
1583   return gst_structure_get_uint64 (structure, fieldname, value);
1584 }
1585
1586 /**
1587  * gst_structure_get_double:
1588  * @structure: a #GstStructure
1589  * @fieldname: the name of a field
1590  * @value: (out): a pointer to a gdouble to set
1591  *
1592  * Sets the double pointed to by @value corresponding to the value of the
1593  * given field.  Caller is responsible for making sure the field exists
1594  * and has the correct type.
1595  *
1596  * Returns: %TRUE if the value could be set correctly. If there was no field
1597  * with @fieldname or the existing field did not contain a double, this
1598  * function returns %FALSE.
1599  */
1600 gboolean
1601 gst_structure_get_double (const GstStructure * structure,
1602     const gchar * fieldname, gdouble * value)
1603 {
1604   GstStructureField *field;
1605
1606   g_return_val_if_fail (structure != NULL, FALSE);
1607   g_return_val_if_fail (fieldname != NULL, FALSE);
1608   g_return_val_if_fail (value != NULL, FALSE);
1609
1610   field = gst_structure_get_field (structure, fieldname);
1611
1612   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DOUBLE)
1613     return FALSE;
1614
1615   *value = gst_g_value_get_double_unchecked (&field->value);
1616
1617   return TRUE;
1618 }
1619
1620 /**
1621  * gst_structure_get_string:
1622  * @structure: a #GstStructure
1623  * @fieldname: the name of a field
1624  *
1625  * Finds the field corresponding to @fieldname, and returns the string
1626  * contained in the field's value.  Caller is responsible for making
1627  * sure the field exists and has the correct type.
1628  *
1629  * The string should not be modified, and remains valid until the next
1630  * call to a gst_structure_*() function with the given structure.
1631  *
1632  * Returns: (nullable): a pointer to the string or %NULL when the
1633  * field did not exist or did not contain a string.
1634  */
1635 const gchar *
1636 gst_structure_get_string (const GstStructure * structure,
1637     const gchar * fieldname)
1638 {
1639   GstStructureField *field;
1640
1641   g_return_val_if_fail (structure != NULL, NULL);
1642   g_return_val_if_fail (fieldname != NULL, NULL);
1643
1644   field = gst_structure_get_field (structure, fieldname);
1645
1646   if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_STRING)
1647     return NULL;
1648
1649   return gst_g_value_get_string_unchecked (&field->value);
1650 }
1651
1652 /**
1653  * gst_structure_get_enum:
1654  * @structure: a #GstStructure
1655  * @fieldname: the name of a field
1656  * @enumtype: the enum type of a field
1657  * @value: (out): a pointer to an int to set
1658  *
1659  * Sets the int pointed to by @value corresponding to the value of the
1660  * given field.  Caller is responsible for making sure the field exists,
1661  * has the correct type and that the enumtype is correct.
1662  *
1663  * Returns: %TRUE if the value could be set correctly. If there was no field
1664  * with @fieldname or the existing field did not contain an enum of the given
1665  * type, this function returns %FALSE.
1666  */
1667 gboolean
1668 gst_structure_get_enum (const GstStructure * structure,
1669     const gchar * fieldname, GType enumtype, gint * value)
1670 {
1671   GstStructureField *field;
1672
1673   g_return_val_if_fail (structure != NULL, FALSE);
1674   g_return_val_if_fail (fieldname != NULL, FALSE);
1675   g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
1676   g_return_val_if_fail (value != NULL, FALSE);
1677
1678   field = gst_structure_get_field (structure, fieldname);
1679
1680   if (field == NULL)
1681     return FALSE;
1682   if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
1683     return FALSE;
1684
1685   *value = g_value_get_enum (&field->value);
1686
1687   return TRUE;
1688 }
1689
1690 /**
1691  * gst_structure_get_fraction:
1692  * @structure: a #GstStructure
1693  * @fieldname: the name of a field
1694  * @value_numerator: (out): a pointer to an int to set
1695  * @value_denominator: (out): a pointer to an int to set
1696  *
1697  * Sets the integers pointed to by @value_numerator and @value_denominator
1698  * corresponding to the value of the given field.  Caller is responsible
1699  * for making sure the field exists and has the correct type.
1700  *
1701  * Returns: %TRUE if the values could be set correctly. If there was no field
1702  * with @fieldname or the existing field did not contain a GstFraction, this
1703  * function returns %FALSE.
1704  */
1705 gboolean
1706 gst_structure_get_fraction (const GstStructure * structure,
1707     const gchar * fieldname, gint * value_numerator, gint * value_denominator)
1708 {
1709   GstStructureField *field;
1710
1711   g_return_val_if_fail (structure != NULL, FALSE);
1712   g_return_val_if_fail (fieldname != NULL, FALSE);
1713   g_return_val_if_fail (value_numerator != NULL, FALSE);
1714   g_return_val_if_fail (value_denominator != NULL, FALSE);
1715
1716   field = gst_structure_get_field (structure, fieldname);
1717
1718   if (field == NULL || G_VALUE_TYPE (&field->value) != GST_TYPE_FRACTION)
1719     return FALSE;
1720
1721   *value_numerator = gst_value_get_fraction_numerator (&field->value);
1722   *value_denominator = gst_value_get_fraction_denominator (&field->value);
1723
1724   return TRUE;
1725 }
1726
1727 /**
1728  * gst_structure_get_flagset:
1729  * @structure: a #GstStructure
1730  * @fieldname: the name of a field
1731  * @value_flags: (out) (allow-none): a pointer to a guint for the flags field
1732  * @value_mask: (out) (allow-none): a pointer to a guint for the mask field
1733  *
1734  * Read the GstFlagSet flags and mask out of the structure into the
1735  * provided pointers.
1736  *
1737  * Returns: %TRUE if the values could be set correctly. If there was no field
1738  * with @fieldname or the existing field did not contain a GstFlagSet, this
1739  * function returns %FALSE.
1740  *
1741  * Since: 1.6
1742  */
1743 gboolean
1744 gst_structure_get_flagset (const GstStructure * structure,
1745     const gchar * fieldname, guint * value_flags, guint * value_mask)
1746 {
1747   GstStructureField *field;
1748
1749   g_return_val_if_fail (structure != NULL, FALSE);
1750   g_return_val_if_fail (fieldname != NULL, FALSE);
1751
1752   field = gst_structure_get_field (structure, fieldname);
1753
1754   if (field == NULL || !GST_VALUE_HOLDS_FLAG_SET (&field->value))
1755     return FALSE;
1756
1757   if (value_flags)
1758     *value_flags = gst_value_get_flagset_flags (&field->value);
1759   if (value_mask)
1760     *value_mask = gst_value_get_flagset_mask (&field->value);
1761
1762   return TRUE;
1763 }
1764
1765 static GType
1766 gst_structure_value_get_generic_type (const GValue * val)
1767 {
1768   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1769       || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1770     GArray *array = g_value_peek_pointer (val);
1771
1772     if (array->len > 0) {
1773       GValue *value = &g_array_index (array, GValue, 0);
1774
1775       return gst_structure_value_get_generic_type (value);
1776     } else {
1777       return G_TYPE_INT;
1778     }
1779   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1780     return G_TYPE_INT;
1781   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT64_RANGE) {
1782     return G_TYPE_INT64;
1783   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1784     return G_TYPE_DOUBLE;
1785   } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
1786     return GST_TYPE_FRACTION;
1787   }
1788   return G_VALUE_TYPE (val);
1789 }
1790
1791 gboolean
1792 priv_gst_structure_append_to_gstring (const GstStructure * structure,
1793     GString * s)
1794 {
1795   GstStructureField *field;
1796   guint i, len;
1797
1798   g_return_val_if_fail (s != NULL, FALSE);
1799
1800   len = GST_STRUCTURE_FIELDS (structure)->len;
1801   for (i = 0; i < len; i++) {
1802     char *t;
1803     GType type;
1804
1805     field = GST_STRUCTURE_FIELD (structure, i);
1806
1807     if (G_VALUE_TYPE (&field->value) == GST_TYPE_ARRAY) {
1808       t = _priv_gst_value_serialize_any_list (&field->value, "< ", " >", FALSE);
1809     } else if (G_VALUE_TYPE (&field->value) == GST_TYPE_LIST) {
1810       t = _priv_gst_value_serialize_any_list (&field->value, "{ ", " }", FALSE);
1811     } else {
1812       t = gst_value_serialize (&field->value);
1813     }
1814
1815     type = gst_structure_value_get_generic_type (&field->value);
1816
1817     g_string_append_len (s, ", ", 2);
1818     /* FIXME: do we need to escape fieldnames? */
1819     g_string_append (s, g_quark_to_string (field->name));
1820     g_string_append_len (s, "=(", 2);
1821     g_string_append (s, _priv_gst_value_gtype_to_abbr (type));
1822     g_string_append_c (s, ')');
1823     if (t) {
1824       g_string_append (s, t);
1825       g_free (t);
1826     } else {
1827       if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, G_TYPE_STRING) &&
1828           !(G_TYPE_CHECK_VALUE_TYPE (&field->value, G_TYPE_POINTER) &&
1829               g_value_get_pointer (&field->value) == NULL))
1830         GST_WARNING ("No value transform to serialize field '%s' of type '%s'",
1831             g_quark_to_string (field->name),
1832             _priv_gst_value_gtype_to_abbr (type));
1833       /* TODO(ensonic): don't print NULL if field->value is not empty */
1834       g_string_append (s, "NULL");
1835     }
1836   }
1837
1838   g_string_append_c (s, ';');
1839   return TRUE;
1840 }
1841
1842 gboolean
1843 priv__gst_structure_append_template_to_gstring (GQuark field_id,
1844     const GValue * value, gpointer user_data)
1845 {
1846   GType type = gst_structure_value_get_generic_type (value);
1847   GString *s = (GString *) user_data;
1848
1849   g_string_append_len (s, ", ", 2);
1850   /* FIXME: do we need to escape fieldnames? */
1851   g_string_append (s, g_quark_to_string (field_id));
1852   g_string_append_len (s, "=(", 2);
1853   g_string_append (s, _priv_gst_value_gtype_to_abbr (type));
1854   g_string_append_c (s, ')');
1855
1856   //TODO(ensonic): table like GstStructureAbbreviation (or extend it)
1857   if (type == G_TYPE_INT) {
1858     g_string_append_len (s, "%i", 2);
1859   } else if (type == G_TYPE_UINT) {
1860     g_string_append_len (s, "%u", 2);
1861   } else if (type == G_TYPE_FLOAT) {
1862     g_string_append_len (s, "%f", 2);
1863   } else if (type == G_TYPE_DOUBLE) {
1864     g_string_append_len (s, "%lf", 3);
1865   } else if (type == G_TYPE_STRING) {
1866     g_string_append_len (s, "%s", 2);
1867   } else if (type == G_TYPE_BOOLEAN) {
1868     /* we normally store this as a string, but can parse it also from an int */
1869     g_string_append_len (s, "%i", 2);
1870   } else if (type == G_TYPE_INT64) {
1871     g_string_append (s, "%" G_GINT64_FORMAT);
1872   } else if (type == G_TYPE_UINT64) {
1873     g_string_append (s, "%" G_GUINT64_FORMAT);
1874   } else if (type == GST_TYPE_STRUCTURE) {
1875     g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
1876   } else if (g_type_is_a (type, G_TYPE_ENUM)
1877       || g_type_is_a (type, G_TYPE_FLAGS)) {
1878     g_string_append_len (s, "%i", 2);
1879   } else if (type == G_TYPE_GTYPE) {
1880     g_string_append_len (s, "%s", 2);
1881   } else if (type == G_TYPE_POINTER) {
1882     g_string_append_len (s, "%p", 2);
1883   } else {
1884     GST_WARNING ("unhandled type: %s", g_type_name (type));
1885     g_string_append (s, "%" GST_WRAPPED_PTR_FORMAT);
1886   }
1887
1888   return TRUE;
1889 }
1890
1891 /**
1892  * gst_structure_to_string:
1893  * @structure: a #GstStructure
1894  *
1895  * Converts @structure to a human-readable string representation.
1896  *
1897  * For debugging purposes its easier to do something like this:
1898  * |[<!-- language="C" -->
1899  * GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
1900  * ]|
1901  * This prints the structure in human readable form.
1902  *
1903  * The current implementation of serialization will lead to unexpected results
1904  * when there are nested #GstCaps / #GstStructure deeper than one level.
1905  *
1906  * Free-function: g_free
1907  *
1908  * Returns: (transfer full): a pointer to string allocated by g_malloc().
1909  *     g_free() after usage.
1910  */
1911 gchar *
1912 gst_structure_to_string (const GstStructure * structure)
1913 {
1914   GString *s;
1915
1916   /* NOTE:  This function is potentially called by the debug system,
1917    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1918    * should be careful to avoid recursion.  This includes any functions
1919    * called by gst_structure_to_string.  In particular, calls should
1920    * not use the GST_PTR_FORMAT extension.  */
1921
1922   g_return_val_if_fail (structure != NULL, NULL);
1923
1924   /* we estimate a minimum size based on the number of fields in order to
1925    * avoid unnecessary reallocs within GString */
1926   s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure));
1927   g_string_append (s, g_quark_to_string (structure->name));
1928   priv_gst_structure_append_to_gstring (structure, s);
1929   return g_string_free (s, FALSE);
1930 }
1931
1932 static gboolean
1933 gst_structure_parse_field (gchar * str,
1934     gchar ** after, GstStructureField * field)
1935 {
1936   gchar *name;
1937   gchar *name_end;
1938   gchar *s;
1939   gchar c;
1940
1941   s = str;
1942
1943   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
1944     s++;
1945   name = s;
1946   if (G_UNLIKELY (!_priv_gst_value_parse_simple_string (s, &name_end))) {
1947     GST_WARNING ("failed to parse simple string, str=%s", str);
1948     return FALSE;
1949   }
1950
1951   s = name_end;
1952   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
1953     s++;
1954
1955   if (G_UNLIKELY (*s != '=')) {
1956     GST_WARNING ("missing assignment operator in the field, str=%s", str);
1957     return FALSE;
1958   }
1959   s++;
1960
1961   c = *name_end;
1962   *name_end = '\0';
1963   field->name = g_quark_from_string (name);
1964   GST_DEBUG ("trying field name '%s'", name);
1965   *name_end = c;
1966
1967   if (G_UNLIKELY (!_priv_gst_value_parse_value (s, &s, &field->value,
1968               G_TYPE_INVALID))) {
1969     GST_WARNING ("failed to parse value %s", str);
1970     return FALSE;
1971   }
1972
1973   *after = s;
1974   return TRUE;
1975 }
1976
1977 gboolean
1978 priv_gst_structure_parse_name (gchar * str, gchar ** start, gchar ** end,
1979     gchar ** next)
1980 {
1981   char *w;
1982   char *r;
1983
1984   r = str;
1985
1986   /* skip spaces (FIXME: _isspace treats tabs and newlines as space!) */
1987   while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
1988               && g_ascii_isspace (r[1]))))
1989     r++;
1990
1991   *start = r;
1992
1993   if (G_UNLIKELY (!_priv_gst_value_parse_string (r, &w, &r, TRUE))) {
1994     GST_WARNING ("Failed to parse structure string '%s'", str);
1995     return FALSE;
1996   }
1997
1998   *end = w;
1999   *next = r;
2000
2001   return TRUE;
2002 }
2003
2004 gboolean
2005 priv_gst_structure_parse_fields (gchar * str, gchar ** end,
2006     GstStructure * structure)
2007 {
2008   gchar *r;
2009   GstStructureField field;
2010
2011   r = str;
2012
2013   do {
2014     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2015                 && g_ascii_isspace (r[1]))))
2016       r++;
2017     if (*r == ';') {
2018       /* end of structure, get the next char and finish */
2019       r++;
2020       break;
2021     }
2022     if (*r == '\0') {
2023       /* accept \0 as end delimiter */
2024       break;
2025     }
2026     if (G_UNLIKELY (*r != ',')) {
2027       GST_WARNING ("Failed to find delimiter, r=%s", r);
2028       return FALSE;
2029     }
2030     r++;
2031     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2032                 && g_ascii_isspace (r[1]))))
2033       r++;
2034
2035     memset (&field, 0, sizeof (field));
2036     if (G_UNLIKELY (!gst_structure_parse_field (r, &r, &field))) {
2037       GST_WARNING ("Failed to parse field, r=%s", r);
2038       return FALSE;
2039     }
2040     gst_structure_set_field (structure, &field);
2041   } while (TRUE);
2042
2043   *end = r;
2044
2045   return TRUE;
2046 }
2047
2048 /**
2049  * gst_structure_new_from_string:
2050  * @string: a string representation of a #GstStructure
2051  *
2052  * Creates a #GstStructure from a string representation.
2053  * If end is not %NULL, a pointer to the place inside the given string
2054  * where parsing ended will be returned.
2055  *
2056  * The current implementation of serialization will lead to unexpected results
2057  * when there are nested #GstCaps / #GstStructure deeper than one level.
2058  *
2059  * Free-function: gst_structure_free
2060  *
2061  * Returns: (transfer full) (nullable): a new #GstStructure or %NULL
2062  *     when the string could not be parsed. Free with
2063  *     gst_structure_free() after use.
2064  *
2065  * Since: 1.2
2066  */
2067 GstStructure *
2068 gst_structure_new_from_string (const gchar * string)
2069 {
2070   return gst_structure_from_string (string, NULL);
2071 }
2072
2073 /**
2074  * gst_structure_from_string:
2075  * @string: a string representation of a #GstStructure.
2076  * @end: (out) (allow-none) (transfer none) (skip): pointer to store the end of the string in.
2077  *
2078  * Creates a #GstStructure from a string representation.
2079  * If end is not %NULL, a pointer to the place inside the given string
2080  * where parsing ended will be returned.
2081  *
2082  * Free-function: gst_structure_free
2083  *
2084  * Returns: (transfer full) (nullable): a new #GstStructure or %NULL
2085  *     when the string could not be parsed. Free with
2086  *     gst_structure_free() after use.
2087  */
2088 GstStructure *
2089 gst_structure_from_string (const gchar * string, gchar ** end)
2090 {
2091   char *name;
2092   char *copy;
2093   char *w;
2094   char *r;
2095   char save;
2096   GstStructure *structure = NULL;
2097
2098   g_return_val_if_fail (string != NULL, NULL);
2099
2100   copy = g_strdup (string);
2101   r = copy;
2102
2103   if (!priv_gst_structure_parse_name (r, &name, &w, &r))
2104     goto error;
2105
2106   save = *w;
2107   *w = '\0';
2108   structure = gst_structure_new_empty (name);
2109   *w = save;
2110
2111   if (G_UNLIKELY (structure == NULL))
2112     goto error;
2113
2114   if (!priv_gst_structure_parse_fields (r, &r, structure))
2115     goto error;
2116
2117   if (end)
2118     *end = (char *) string + (r - copy);
2119   else if (*r)
2120     g_warning ("gst_structure_from_string did not consume whole string,"
2121         " but caller did not provide end pointer (\"%s\")", string);
2122
2123   g_free (copy);
2124   return structure;
2125
2126 error:
2127   if (structure)
2128     gst_structure_free (structure);
2129   g_free (copy);
2130   return NULL;
2131 }
2132
2133 static void
2134 gst_structure_transform_to_string (const GValue * src_value,
2135     GValue * dest_value)
2136 {
2137   g_return_if_fail (src_value != NULL);
2138   g_return_if_fail (dest_value != NULL);
2139
2140   dest_value->data[0].v_pointer =
2141       gst_structure_to_string (src_value->data[0].v_pointer);
2142 }
2143
2144 static GstStructure *
2145 gst_structure_copy_conditional (const GstStructure * structure)
2146 {
2147   if (structure)
2148     return gst_structure_copy (structure);
2149   return NULL;
2150 }
2151
2152 /* fixate utility functions */
2153
2154 /**
2155  * gst_structure_fixate_field_nearest_int:
2156  * @structure: a #GstStructure
2157  * @field_name: a field in @structure
2158  * @target: the target value of the fixation
2159  *
2160  * Fixates a #GstStructure by changing the given field to the nearest
2161  * integer to @target that is a subset of the existing field.
2162  *
2163  * Returns: %TRUE if the structure could be fixated
2164  */
2165 gboolean
2166 gst_structure_fixate_field_nearest_int (GstStructure * structure,
2167     const char *field_name, int target)
2168 {
2169   const GValue *value;
2170
2171   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2172   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2173
2174   value = gst_structure_get_value (structure, field_name);
2175
2176   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
2177     /* already fixed */
2178     return FALSE;
2179   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
2180     int x;
2181
2182     x = gst_value_get_int_range_min (value);
2183     if (target < x)
2184       target = x;
2185     x = gst_value_get_int_range_max (value);
2186     if (target > x)
2187       target = x;
2188     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
2189     return TRUE;
2190   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2191     const GValue *list_value;
2192     int i, n;
2193     int best = 0;
2194     int best_index = -1;
2195
2196     n = gst_value_list_get_size (value);
2197     for (i = 0; i < n; i++) {
2198       list_value = gst_value_list_get_value (value, i);
2199       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
2200         int x = gst_g_value_get_int_unchecked (list_value);
2201
2202         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2203           best_index = i;
2204           best = x;
2205         }
2206       }
2207     }
2208     if (best_index != -1) {
2209       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
2210       return TRUE;
2211     }
2212     return FALSE;
2213   }
2214
2215   return FALSE;
2216 }
2217
2218 /**
2219  * gst_structure_fixate_field_nearest_double:
2220  * @structure: a #GstStructure
2221  * @field_name: a field in @structure
2222  * @target: the target value of the fixation
2223  *
2224  * Fixates a #GstStructure by changing the given field to the nearest
2225  * double to @target that is a subset of the existing field.
2226  *
2227  * Returns: %TRUE if the structure could be fixated
2228  */
2229 gboolean
2230 gst_structure_fixate_field_nearest_double (GstStructure * structure,
2231     const char *field_name, double target)
2232 {
2233   const GValue *value;
2234
2235   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2236   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2237
2238   value = gst_structure_get_value (structure, field_name);
2239
2240   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
2241     /* already fixed */
2242     return FALSE;
2243   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
2244     double x;
2245
2246     x = gst_value_get_double_range_min (value);
2247     if (target < x)
2248       target = x;
2249     x = gst_value_get_double_range_max (value);
2250     if (target > x)
2251       target = x;
2252     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
2253     return TRUE;
2254   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2255     const GValue *list_value;
2256     int i, n;
2257     double best = 0;
2258     int best_index = -1;
2259
2260     n = gst_value_list_get_size (value);
2261     for (i = 0; i < n; i++) {
2262       list_value = gst_value_list_get_value (value, i);
2263       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
2264         double x = gst_g_value_get_double_unchecked (list_value);
2265
2266         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2267           best_index = i;
2268           best = x;
2269         }
2270       }
2271     }
2272     if (best_index != -1) {
2273       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
2274       return TRUE;
2275     }
2276     return FALSE;
2277   }
2278
2279   return FALSE;
2280
2281 }
2282
2283 /**
2284  * gst_structure_fixate_field_boolean:
2285  * @structure: a #GstStructure
2286  * @field_name: a field in @structure
2287  * @target: the target value of the fixation
2288  *
2289  * Fixates a #GstStructure by changing the given @field_name field to the given
2290  * @target boolean if that field is not fixed yet.
2291  *
2292  * Returns: %TRUE if the structure could be fixated
2293  */
2294 gboolean
2295 gst_structure_fixate_field_boolean (GstStructure * structure,
2296     const char *field_name, gboolean target)
2297 {
2298   const GValue *value;
2299
2300   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2301   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2302
2303   value = gst_structure_get_value (structure, field_name);
2304
2305   if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
2306     /* already fixed */
2307     return FALSE;
2308   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2309     const GValue *list_value;
2310     int i, n;
2311     int best = 0;
2312     int best_index = -1;
2313
2314     n = gst_value_list_get_size (value);
2315     for (i = 0; i < n; i++) {
2316       list_value = gst_value_list_get_value (value, i);
2317       if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
2318         gboolean x = gst_g_value_get_boolean_unchecked (list_value);
2319
2320         if (best_index == -1 || x == target) {
2321           best_index = i;
2322           best = x;
2323         }
2324       }
2325     }
2326     if (best_index != -1) {
2327       gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
2328       return TRUE;
2329     }
2330     return FALSE;
2331   }
2332
2333   return FALSE;
2334 }
2335
2336 /**
2337  * gst_structure_fixate_field_string:
2338  * @structure: a #GstStructure
2339  * @field_name: a field in @structure
2340  * @target: the target value of the fixation
2341  *
2342  * Fixates a #GstStructure by changing the given @field_name field to the given
2343  * @target string if that field is not fixed yet.
2344  *
2345  * Returns: %TRUE if the structure could be fixated
2346  */
2347 gboolean
2348 gst_structure_fixate_field_string (GstStructure * structure,
2349     const gchar * field_name, const gchar * target)
2350 {
2351   const GValue *value;
2352
2353   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2354   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2355
2356   value = gst_structure_get_value (structure, field_name);
2357
2358   if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
2359     /* already fixed */
2360     return FALSE;
2361   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2362     const GValue *list_value;
2363     int i, n;
2364     const gchar *best = NULL;
2365     int best_index = -1;
2366
2367     n = gst_value_list_get_size (value);
2368     for (i = 0; i < n; i++) {
2369       list_value = gst_value_list_get_value (value, i);
2370       if (G_VALUE_TYPE (list_value) == G_TYPE_STRING) {
2371         const gchar *x = g_value_get_string (list_value);
2372
2373         if (best_index == -1 || g_str_equal (x, target)) {
2374           best_index = i;
2375           best = x;
2376         }
2377       }
2378     }
2379     if (best_index != -1) {
2380       gst_structure_set (structure, field_name, G_TYPE_STRING, best, NULL);
2381       return TRUE;
2382     }
2383     return FALSE;
2384   }
2385
2386   return FALSE;
2387 }
2388
2389 /**
2390  * gst_structure_fixate_field_nearest_fraction:
2391  * @structure: a #GstStructure
2392  * @field_name: a field in @structure
2393  * @target_numerator: The numerator of the target value of the fixation
2394  * @target_denominator: The denominator of the target value of the fixation
2395  *
2396  * Fixates a #GstStructure by changing the given field to the nearest
2397  * fraction to @target_numerator/@target_denominator that is a subset
2398  * of the existing field.
2399  *
2400  * Returns: %TRUE if the structure could be fixated
2401  */
2402 gboolean
2403 gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
2404     const char *field_name, const gint target_numerator,
2405     const gint target_denominator)
2406 {
2407   const GValue *value;
2408
2409   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2410   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2411   g_return_val_if_fail (target_denominator != 0, FALSE);
2412
2413   value = gst_structure_get_value (structure, field_name);
2414
2415   if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
2416     /* already fixed */
2417     return FALSE;
2418   } else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
2419     const GValue *x, *new_value;
2420     GValue target = { 0 };
2421     g_value_init (&target, GST_TYPE_FRACTION);
2422     gst_value_set_fraction (&target, target_numerator, target_denominator);
2423
2424     new_value = &target;
2425     x = gst_value_get_fraction_range_min (value);
2426     if (gst_value_compare (&target, x) == GST_VALUE_LESS_THAN)
2427       new_value = x;
2428     x = gst_value_get_fraction_range_max (value);
2429     if (gst_value_compare (&target, x) == GST_VALUE_GREATER_THAN)
2430       new_value = x;
2431
2432     gst_structure_set_value (structure, field_name, new_value);
2433     g_value_unset (&target);
2434     return TRUE;
2435   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2436     const GValue *list_value;
2437     int i, n;
2438     const GValue *best = NULL;
2439     gdouble target;
2440     gdouble cur_diff;
2441     gdouble best_diff = G_MAXDOUBLE;
2442
2443     target = (gdouble) target_numerator / (gdouble) target_denominator;
2444
2445     GST_DEBUG ("target %g, best %g", target, best_diff);
2446
2447     best = NULL;
2448
2449     n = gst_value_list_get_size (value);
2450     for (i = 0; i < n; i++) {
2451       list_value = gst_value_list_get_value (value, i);
2452       if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
2453         gint num, denom;
2454         gdouble list_double;
2455
2456         num = gst_value_get_fraction_numerator (list_value);
2457         denom = gst_value_get_fraction_denominator (list_value);
2458
2459         list_double = ((gdouble) num / (gdouble) denom);
2460         cur_diff = target - list_double;
2461
2462         GST_DEBUG ("curr diff %g, list %g", cur_diff, list_double);
2463
2464         if (cur_diff < 0)
2465           cur_diff = -cur_diff;
2466
2467         if (!best || cur_diff < best_diff) {
2468           GST_DEBUG ("new best %g", list_double);
2469           best = list_value;
2470           best_diff = cur_diff;
2471         }
2472       }
2473     }
2474     if (best != NULL) {
2475       gst_structure_set_value (structure, field_name, best);
2476       return TRUE;
2477     }
2478   }
2479
2480   return FALSE;
2481 }
2482
2483 static gboolean
2484 default_fixate (GQuark field_id, const GValue * value, gpointer data)
2485 {
2486   GstStructure *s = data;
2487   GValue v = { 0 };
2488
2489   if (gst_value_fixate (&v, value)) {
2490     gst_structure_id_take_value (s, field_id, &v);
2491   }
2492   return TRUE;
2493 }
2494
2495 /**
2496  * gst_structure_fixate_field:
2497  * @structure: a #GstStructure
2498  * @field_name: a field in @structure
2499  *
2500  * Fixates a #GstStructure by changing the given field with its fixated value.
2501  *
2502  * Returns: %TRUE if the structure field could be fixated
2503  */
2504 gboolean
2505 gst_structure_fixate_field (GstStructure * structure, const char *field_name)
2506 {
2507   GstStructureField *field;
2508
2509   g_return_val_if_fail (structure != NULL, FALSE);
2510   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2511
2512   if (!(field = gst_structure_get_field (structure, field_name)))
2513     return FALSE;
2514
2515   return default_fixate (field->name, &field->value, structure);
2516 }
2517
2518 /* our very own version of G_VALUE_LCOPY that allows NULL return locations
2519  * (useful for message parsing functions where the return location is user
2520  * supplied and the user may pass %NULL if the value isn't of interest) */
2521 #define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname)           \
2522 G_STMT_START {                                                                \
2523   const GValue *_value = (value);                                             \
2524   guint _flags = (flags);                                                     \
2525   GType _value_type = G_VALUE_TYPE (_value);                                  \
2526   GTypeValueTable *_vtable = g_type_value_table_peek (_value_type);           \
2527   const gchar *_lcopy_format = _vtable->lcopy_format;                         \
2528   GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };      \
2529   guint _n_values = 0;                                                        \
2530                                                                               \
2531   while (*_lcopy_format != '\0') {                                            \
2532     g_assert (*_lcopy_format == G_VALUE_COLLECT_POINTER);                     \
2533     _cvalues[_n_values++].v_pointer = va_arg ((var_args), gpointer);          \
2534     _lcopy_format++;                                                          \
2535   }                                                                           \
2536   if (_n_values == 2 && !!_cvalues[0].v_pointer != !!_cvalues[1].v_pointer) { \
2537     *(__error) = g_strdup_printf ("either all or none of the return "         \
2538         "locations for field '%s' need to be NULL", fieldname);               \
2539   } else if (_cvalues[0].v_pointer != NULL) {                                 \
2540     *(__error) = _vtable->lcopy_value (_value, _n_values, _cvalues, _flags);  \
2541   }                                                                           \
2542 } G_STMT_END
2543
2544 /**
2545  * gst_structure_get_valist:
2546  * @structure: a #GstStructure
2547  * @first_fieldname: the name of the first field to read
2548  * @args: variable arguments
2549  *
2550  * Parses the variable arguments and reads fields from @structure accordingly.
2551  * valist-variant of gst_structure_get(). Look at the documentation of
2552  * gst_structure_get() for more details.
2553  *
2554  * Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
2555  */
2556 gboolean
2557 gst_structure_get_valist (const GstStructure * structure,
2558     const char *first_fieldname, va_list args)
2559 {
2560   const char *field_name;
2561   GType expected_type = G_TYPE_INVALID;
2562
2563   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2564   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2565
2566   field_name = first_fieldname;
2567   while (field_name) {
2568     const GValue *val = NULL;
2569     gchar *err = NULL;
2570
2571     expected_type = va_arg (args, GType);
2572
2573     val = gst_structure_get_value (structure, field_name);
2574
2575     if (val == NULL)
2576       goto no_such_field;
2577
2578     if (G_VALUE_TYPE (val) != expected_type)
2579       goto wrong_type;
2580
2581     GST_VALUE_LCOPY (val, args, 0, &err, field_name);
2582     if (err) {
2583       g_warning ("%s: %s", G_STRFUNC, err);
2584       g_free (err);
2585       return FALSE;
2586     }
2587
2588     field_name = va_arg (args, const gchar *);
2589   }
2590
2591   return TRUE;
2592
2593 /* ERRORS */
2594 no_such_field:
2595   {
2596     GST_INFO ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2597         field_name, structure);
2598     return FALSE;
2599   }
2600 wrong_type:
2601   {
2602     GST_INFO ("Expected field '%s' in structure to be of type '%s', but "
2603         "field was of type '%s': %" GST_PTR_FORMAT, field_name,
2604         GST_STR_NULL (g_type_name (expected_type)),
2605         G_VALUE_TYPE_NAME (gst_structure_get_value (structure, field_name)),
2606         structure);
2607     return FALSE;
2608   }
2609 }
2610
2611 /**
2612  * gst_structure_id_get_valist:
2613  * @structure: a #GstStructure
2614  * @first_field_id: the quark of the first field to read
2615  * @args: variable arguments
2616  *
2617  * Parses the variable arguments and reads fields from @structure accordingly.
2618  * valist-variant of gst_structure_id_get(). Look at the documentation of
2619  * gst_structure_id_get() for more details.
2620  *
2621  * Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
2622  */
2623 gboolean
2624 gst_structure_id_get_valist (const GstStructure * structure,
2625     GQuark first_field_id, va_list args)
2626 {
2627   GQuark field_id;
2628   GType expected_type = G_TYPE_INVALID;
2629
2630   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2631   g_return_val_if_fail (first_field_id != 0, FALSE);
2632
2633   field_id = first_field_id;
2634   while (field_id) {
2635     const GValue *val = NULL;
2636     gchar *err = NULL;
2637
2638     expected_type = va_arg (args, GType);
2639
2640     val = gst_structure_id_get_value (structure, field_id);
2641
2642     if (val == NULL)
2643       goto no_such_field;
2644
2645     if (G_VALUE_TYPE (val) != expected_type)
2646       goto wrong_type;
2647
2648     GST_VALUE_LCOPY (val, args, 0, &err, g_quark_to_string (field_id));
2649     if (err) {
2650       g_warning ("%s: %s", G_STRFUNC, err);
2651       g_free (err);
2652       return FALSE;
2653     }
2654
2655     field_id = va_arg (args, GQuark);
2656   }
2657
2658   return TRUE;
2659
2660 /* ERRORS */
2661 no_such_field:
2662   {
2663     GST_DEBUG ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2664         GST_STR_NULL (g_quark_to_string (field_id)), structure);
2665     return FALSE;
2666   }
2667 wrong_type:
2668   {
2669     GST_DEBUG ("Expected field '%s' in structure to be of type '%s', but "
2670         "field was of type '%s': %" GST_PTR_FORMAT,
2671         g_quark_to_string (field_id),
2672         GST_STR_NULL (g_type_name (expected_type)),
2673         G_VALUE_TYPE_NAME (gst_structure_id_get_value (structure, field_id)),
2674         structure);
2675     return FALSE;
2676   }
2677 }
2678
2679 /**
2680  * gst_structure_get:
2681  * @structure: a #GstStructure
2682  * @first_fieldname: the name of the first field to read
2683  * @...: variable arguments
2684  *
2685  * Parses the variable arguments and reads fields from @structure accordingly.
2686  * Variable arguments should be in the form field name, field type
2687  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2688  * The last variable argument should be %NULL.
2689  *
2690  * For refcounted (mini)objects you will receive a new reference which
2691  * you must release with a suitable _unref() when no longer needed. For
2692  * strings and boxed types you will receive a copy which you will need to
2693  * release with either g_free() or the suitable function for the boxed type.
2694  *
2695  * Returns: %FALSE if there was a problem reading any of the fields (e.g.
2696  *     because the field requested did not exist, or was of a type other
2697  *     than the type specified), otherwise %TRUE.
2698  */
2699 gboolean
2700 gst_structure_get (const GstStructure * structure, const char *first_fieldname,
2701     ...)
2702 {
2703   gboolean ret;
2704   va_list args;
2705
2706   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2707   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2708
2709   va_start (args, first_fieldname);
2710   ret = gst_structure_get_valist (structure, first_fieldname, args);
2711   va_end (args);
2712
2713   return ret;
2714 }
2715
2716 /**
2717  * gst_structure_id_get:
2718  * @structure: a #GstStructure
2719  * @first_field_id: the quark of the first field to read
2720  * @...: variable arguments
2721  *
2722  * Parses the variable arguments and reads fields from @structure accordingly.
2723  * Variable arguments should be in the form field id quark, field type
2724  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2725  * The last variable argument should be %NULL (technically it should be a
2726  * 0 quark, but we require %NULL so compilers that support it can check for
2727  * the %NULL terminator and warn if it's not there).
2728  *
2729  * This function is just like gst_structure_get() only that it is slightly
2730  * more efficient since it saves the string-to-quark lookup in the global
2731  * quark hashtable.
2732  *
2733  * For refcounted (mini)objects you will receive a new reference which
2734  * you must release with a suitable _unref() when no longer needed. For
2735  * strings and boxed types you will receive a copy which you will need to
2736  * release with either g_free() or the suitable function for the boxed type.
2737  *
2738  * Returns: %FALSE if there was a problem reading any of the fields (e.g.
2739  *     because the field requested did not exist, or was of a type other
2740  *     than the type specified), otherwise %TRUE.
2741  */
2742 gboolean
2743 gst_structure_id_get (const GstStructure * structure, GQuark first_field_id,
2744     ...)
2745 {
2746   gboolean ret;
2747   va_list args;
2748
2749   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2750   g_return_val_if_fail (first_field_id != 0, FALSE);
2751
2752   va_start (args, first_field_id);
2753   ret = gst_structure_id_get_valist (structure, first_field_id, args);
2754   va_end (args);
2755
2756   return ret;
2757 }
2758
2759 static gboolean
2760 gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
2761     gpointer data)
2762 {
2763   const GstStructure *struct1 = (const GstStructure *) data;
2764   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
2765
2766   if (G_UNLIKELY (val1 == NULL))
2767     return FALSE;
2768   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
2769     return TRUE;
2770   }
2771
2772   return FALSE;
2773 }
2774
2775 /**
2776  * gst_structure_is_equal:
2777  * @structure1: a #GstStructure.
2778  * @structure2: a #GstStructure.
2779  *
2780  * Tests if the two #GstStructure are equal.
2781  *
2782  * Returns: %TRUE if the two structures have the same name and field.
2783  **/
2784 gboolean
2785 gst_structure_is_equal (const GstStructure * structure1,
2786     const GstStructure * structure2)
2787 {
2788   g_return_val_if_fail (GST_IS_STRUCTURE (structure1), FALSE);
2789   g_return_val_if_fail (GST_IS_STRUCTURE (structure2), FALSE);
2790
2791   if (G_UNLIKELY (structure1 == structure2))
2792     return TRUE;
2793
2794   if (structure1->name != structure2->name) {
2795     return FALSE;
2796   }
2797   if (GST_STRUCTURE_FIELDS (structure1)->len !=
2798       GST_STRUCTURE_FIELDS (structure2)->len) {
2799     return FALSE;
2800   }
2801
2802   return gst_structure_foreach (structure1, gst_structure_is_equal_foreach,
2803       (gpointer) structure2);
2804 }
2805
2806
2807 typedef struct
2808 {
2809   GstStructure *dest;
2810   const GstStructure *intersect;
2811 }
2812 IntersectData;
2813
2814 static gboolean
2815 gst_structure_intersect_field1 (GQuark id, const GValue * val1, gpointer data)
2816 {
2817   IntersectData *idata = (IntersectData *) data;
2818   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
2819
2820   if (G_UNLIKELY (val2 == NULL)) {
2821     gst_structure_id_set_value (idata->dest, id, val1);
2822   } else {
2823     GValue dest_value = { 0 };
2824     if (gst_value_intersect (&dest_value, val1, val2)) {
2825       gst_structure_id_take_value (idata->dest, id, &dest_value);
2826     } else {
2827       return FALSE;
2828     }
2829   }
2830   return TRUE;
2831 }
2832
2833 static gboolean
2834 gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
2835 {
2836   IntersectData *idata = (IntersectData *) data;
2837   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
2838
2839   if (G_UNLIKELY (val2 == NULL)) {
2840     gst_structure_id_set_value (idata->dest, id, val1);
2841   }
2842   return TRUE;
2843 }
2844
2845 /**
2846  * gst_structure_intersect:
2847  * @struct1: a #GstStructure
2848  * @struct2: a #GstStructure
2849  *
2850  * Intersects @struct1 and @struct2 and returns the intersection.
2851  *
2852  * Returns: (nullable): Intersection of @struct1 and @struct2
2853  */
2854 GstStructure *
2855 gst_structure_intersect (const GstStructure * struct1,
2856     const GstStructure * struct2)
2857 {
2858   IntersectData data;
2859
2860   g_assert (struct1 != NULL);
2861   g_assert (struct2 != NULL);
2862
2863   if (G_UNLIKELY (struct1->name != struct2->name))
2864     return NULL;
2865
2866   /* copy fields from struct1 which we have not in struct2 to target
2867    * intersect if we have the field in both */
2868   data.dest = gst_structure_new_id_empty (struct1->name);
2869   data.intersect = struct2;
2870   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
2871               gst_structure_intersect_field1, &data)))
2872     goto error;
2873
2874   /* copy fields from struct2 which we have not in struct1 to target */
2875   data.intersect = struct1;
2876   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
2877               gst_structure_intersect_field2, &data)))
2878     goto error;
2879
2880   return data.dest;
2881
2882 error:
2883   gst_structure_free (data.dest);
2884   return NULL;
2885 }
2886
2887 static gboolean
2888 gst_caps_structure_can_intersect_field (GQuark id, const GValue * val1,
2889     gpointer data)
2890 {
2891   GstStructure *other = (GstStructure *) data;
2892   const GValue *val2 = gst_structure_id_get_value (other, id);
2893
2894   if (G_LIKELY (val2)) {
2895     if (!gst_value_can_intersect (val1, val2)) {
2896       return FALSE;
2897     } else {
2898       gint eq = gst_value_compare (val1, val2);
2899
2900       if (eq == GST_VALUE_UNORDERED) {
2901         /* we need to try interseting */
2902         if (!gst_value_intersect (NULL, val1, val2)) {
2903           return FALSE;
2904         }
2905       } else if (eq != GST_VALUE_EQUAL) {
2906         return FALSE;
2907       }
2908     }
2909   }
2910   return TRUE;
2911 }
2912
2913 /**
2914  * gst_structure_can_intersect:
2915  * @struct1: a #GstStructure
2916  * @struct2: a #GstStructure
2917  *
2918  * Tries intersecting @struct1 and @struct2 and reports whether the result
2919  * would not be empty.
2920  *
2921  * Returns: %TRUE if intersection would not be empty
2922  */
2923 gboolean
2924 gst_structure_can_intersect (const GstStructure * struct1,
2925     const GstStructure * struct2)
2926 {
2927   g_return_val_if_fail (GST_IS_STRUCTURE (struct1), FALSE);
2928   g_return_val_if_fail (GST_IS_STRUCTURE (struct2), FALSE);
2929
2930   if (G_UNLIKELY (struct1->name != struct2->name))
2931     return FALSE;
2932
2933   /* tries to intersect if we have the field in both */
2934   return gst_structure_foreach ((GstStructure *) struct1,
2935       gst_caps_structure_can_intersect_field, (gpointer) struct2);
2936 }
2937
2938 static gboolean
2939 gst_caps_structure_is_superset_field (GQuark field_id, const GValue * value,
2940     gpointer user_data)
2941 {
2942   GstStructure *subset = user_data;
2943   const GValue *other;
2944   int comparison;
2945
2946   if (!(other = gst_structure_id_get_value (subset, field_id)))
2947     /* field is missing in the subset => no subset */
2948     return FALSE;
2949
2950   comparison = gst_value_compare (value, other);
2951
2952   /* equal values are subset */
2953   if (comparison == GST_VALUE_EQUAL)
2954     return TRUE;
2955
2956   /* ordered, but unequal, values are not */
2957   if (comparison != GST_VALUE_UNORDERED)
2958     return FALSE;
2959
2960   return gst_value_is_subset (other, value);
2961 }
2962
2963 /**
2964  * gst_structure_is_subset:
2965  * @subset: a #GstStructure
2966  * @superset: a potentially greater #GstStructure
2967  *
2968  * Checks if @subset is a subset of @superset, i.e. has the same
2969  * structure name and for all fields that are existing in @superset,
2970  * @subset has a value that is a subset of the value in @superset.
2971  *
2972  * Returns: %TRUE if @subset is a subset of @superset
2973  */
2974 gboolean
2975 gst_structure_is_subset (const GstStructure * subset,
2976     const GstStructure * superset)
2977 {
2978   if ((superset->name != subset->name) ||
2979       (gst_structure_n_fields (superset) > gst_structure_n_fields (subset)))
2980     return FALSE;
2981
2982   return gst_structure_foreach ((GstStructure *) superset,
2983       gst_caps_structure_is_superset_field, (gpointer) subset);
2984 }
2985
2986
2987 /**
2988  * gst_structure_fixate:
2989  * @structure: a #GstStructure
2990  *
2991  * Fixate all values in @structure using gst_value_fixate().
2992  * @structure will be modified in-place and should be writable.
2993  */
2994 void
2995 gst_structure_fixate (GstStructure * structure)
2996 {
2997   g_return_if_fail (GST_IS_STRUCTURE (structure));
2998
2999   gst_structure_foreach (structure, default_fixate, structure);
3000 }
3001
3002 static gboolean
3003 _gst_structure_get_any_list (GstStructure * structure, GType type,
3004     const gchar * fieldname, GValueArray ** array)
3005 {
3006   GstStructureField *field;
3007   GValue val = G_VALUE_INIT;
3008
3009   g_return_val_if_fail (structure != NULL, FALSE);
3010   g_return_val_if_fail (fieldname != NULL, FALSE);
3011   g_return_val_if_fail (array != NULL, FALSE);
3012
3013   field = gst_structure_get_field (structure, fieldname);
3014
3015   if (field == NULL || G_VALUE_TYPE (&field->value) != type)
3016     return FALSE;
3017
3018   g_value_init (&val, G_TYPE_VALUE_ARRAY);
3019
3020   if (g_value_transform (&field->value, &val)) {
3021     *array = g_value_get_boxed (&val);
3022     return TRUE;
3023   }
3024
3025   g_value_unset (&val);
3026   return FALSE;
3027 }
3028
3029 /**
3030  * gst_structure_get_array:
3031  * @structure: a #GstStructure
3032  * @fieldname: the name of a field
3033  * @array: (out): a pointer to a #GValueArray
3034  *
3035  * This is useful in language bindings where unknown #GValue types are not
3036  * supported. This function will convert the %GST_TYPE_ARRAY and
3037  * %GST_TYPE_LIST into a newly allocated #GValueArray and return it through
3038  * @array. Be aware that this is slower then getting the #GValue directly.
3039  *
3040  * Returns: %TRUE if the value could be set correctly. If there was no field
3041  * with @fieldname or the existing field did not contain an int, this function
3042  * returns %FALSE.
3043  */
3044 gboolean
3045 gst_structure_get_array (GstStructure * structure, const gchar * fieldname,
3046     GValueArray ** array)
3047 {
3048   return _gst_structure_get_any_list (structure, GST_TYPE_ARRAY, fieldname,
3049       array);
3050 }
3051
3052 /**
3053  * gst_structure_get_list:
3054  * @structure: a #GstStructure
3055  * @fieldname: the name of a field
3056  * @array: (out): a pointer to a #GValueArray
3057  *
3058  * This is useful in language bindings where unknown #GValue types are not
3059  * supported. This function will convert the %GST_TYPE_ARRAY and
3060  * %GST_TYPE_LIST into a newly allocated GValueArray and return it through
3061  * @array. Be aware that this is slower then getting the #GValue directly.
3062  *
3063  * Returns: %TRUE if the value could be set correctly. If there was no field
3064  * with @fieldname or the existing field did not contain an int, this function
3065  * returns %FALSE.
3066  *
3067  * Since 1.12
3068  */
3069 gboolean
3070 gst_structure_get_list (GstStructure * structure, const gchar * fieldname,
3071     GValueArray ** array)
3072 {
3073   return _gst_structure_get_any_list (structure, GST_TYPE_LIST, fieldname,
3074       array);
3075 }
3076
3077 static void
3078 _gst_structure_set_any_list (GstStructure * structure, GType type,
3079     const gchar * fieldname, const GValueArray * array)
3080 {
3081   GValue arval = G_VALUE_INIT;
3082   GValue value = G_VALUE_INIT;
3083
3084   g_return_if_fail (structure != NULL);
3085   g_return_if_fail (fieldname != NULL);
3086   g_return_if_fail (array != NULL);
3087   g_return_if_fail (IS_MUTABLE (structure));
3088
3089   g_value_init (&value, type);
3090   g_value_init (&arval, G_TYPE_VALUE_ARRAY);
3091   g_value_set_static_boxed (&arval, array);
3092
3093   if (g_value_transform (&arval, &value)) {
3094     gst_structure_id_set_value_internal (structure,
3095         g_quark_from_string (fieldname), &value);
3096   } else {
3097     g_warning ("Failed to convert a GValueArray");
3098   }
3099
3100   g_value_unset (&arval);
3101   g_value_unset (&value);
3102 }
3103
3104 /**
3105  * gst_structure_set_array:
3106  * @structure: a #GstStructure
3107  * @fieldname: the name of a field
3108  * @array: a pointer to a #GValueArray
3109  *
3110  * This is useful in language bindings where unknown GValue types are not
3111  * supported. This function will convert a @array to %GST_TYPE_ARRAY and set
3112  * the field specified by @fieldname.  Be aware that this is slower then using
3113  * %GST_TYPE_ARRAY in a #GValue directly.
3114  *
3115  * Since 1.12
3116  */
3117 void
3118 gst_structure_set_array (GstStructure * structure, const gchar * fieldname,
3119     const GValueArray * array)
3120 {
3121   _gst_structure_set_any_list (structure, GST_TYPE_ARRAY, fieldname, array);
3122 }
3123
3124 /**
3125  * gst_structure_set_list:
3126  * @structure: a #GstStructure
3127  * @fieldname: the name of a field
3128  * @array: a pointer to a #GValueArray
3129  *
3130  * This is useful in language bindings where unknown GValue types are not
3131  * supported. This function will convert a @array to %GST_TYPE_ARRAY and set
3132  * the field specified by @fieldname. Be aware that this is slower then using
3133  * %GST_TYPE_ARRAY in a #GValue directly.
3134  *
3135  * Since 1.12
3136  */
3137 void
3138 gst_structure_set_list (GstStructure * structure, const gchar * fieldname,
3139     const GValueArray * array)
3140 {
3141   _gst_structure_set_any_list (structure, GST_TYPE_LIST, fieldname, array);
3142 }