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