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