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