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