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