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