various style fixes
[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  *
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <string.h>
33
34 #include "gst_private.h"
35 #include <gst/gst.h>
36 #include <gobject/gvaluecollector.h>
37
38 typedef struct _GstStructureField GstStructureField;
39
40 struct _GstStructureField
41 {
42   GQuark name;
43   GValue value;
44 };
45
46 #define GST_STRUCTURE_FIELD(structure, index) \
47     &g_array_index((structure)->fields, GstStructureField, (index))
48
49 #define IS_MUTABLE(structure) \
50     (!(structure)->parent_refcount || \
51      g_atomic_int_get ((structure)->parent_refcount) == 1)
52
53 static void gst_structure_set_field (GstStructure * structure,
54     GstStructureField * field);
55 static GstStructureField *gst_structure_get_field (const GstStructure *
56     structure, const gchar * fieldname);
57 static GstStructureField *gst_structure_id_get_field (const GstStructure *
58     structure, GQuark field);
59 static void gst_structure_transform_to_string (const GValue * src_value,
60     GValue * dest_value);
61 static GstStructure *gst_structure_copy_conditional (const GstStructure *
62     structure);
63 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
64     GValue * value, GType default_type);
65 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
66
67 GType
68 gst_structure_get_type (void)
69 {
70   static GType gst_structure_type = 0;
71
72   if (!gst_structure_type) {
73     gst_structure_type = g_boxed_type_register_static ("GstStructure",
74         (GBoxedCopyFunc) gst_structure_copy_conditional,
75         (GBoxedFreeFunc) gst_structure_free);
76
77     g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
78         gst_structure_transform_to_string);
79   }
80
81   return gst_structure_type;
82 }
83
84 static GstStructure *
85 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
86 {
87   GstStructure *structure;
88
89   structure = g_new0 (GstStructure, 1);
90   structure->type = gst_structure_get_type ();
91   structure->name = quark;
92   structure->fields =
93       g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc);
94
95   return structure;
96 }
97
98 /**
99  * gst_structure_id_empty_new:
100  * @quark: name of new structure
101  *
102  * Creates a new, empty #GstStructure with the given name.
103  *
104  * Returns: a new, empty #GstStructure
105  */
106 GstStructure *
107 gst_structure_id_empty_new (GQuark quark)
108 {
109   g_return_val_if_fail (quark != 0, NULL);
110
111   return gst_structure_id_empty_new_with_size (quark, 0);
112 }
113
114 /**
115  * gst_structure_empty_new:
116  * @name: name of new structure
117  *
118  * Creates a new, empty #GstStructure with the given name.
119  *
120  * Returns: a new, empty #GstStructure
121  */
122 GstStructure *
123 gst_structure_empty_new (const gchar * name)
124 {
125   g_return_val_if_fail (name != NULL, NULL);
126
127   return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
128 }
129
130 /**
131  * gst_structure_new:
132  * @name: name of new structure
133  * @firstfield: name of first field to set
134  * @...: additional arguments
135  *
136  * Creates a new #GstStructure with the given name.  Parses the
137  * list of variable arguments and sets fields to the values listed.
138  * Variable arguments should be passed as field name, field type,
139  * and value.  Last variable argument should be NULL.
140  *
141  * Returns: a new #GstStructure
142  */
143 GstStructure *
144 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
145 {
146   GstStructure *structure;
147   va_list varargs;
148
149   g_return_val_if_fail (name != NULL, NULL);
150
151   va_start (varargs, firstfield);
152
153   structure = gst_structure_new_valist (name, firstfield, varargs);
154
155   va_end (varargs);
156
157   return structure;
158 }
159
160 /**
161  * gst_structure_new_valist:
162  * @name: name of new structure
163  * @firstfield: name of first field to set
164  * @varargs: variable argument list
165  *
166  * Creates a new #GstStructure with the given name.  Structure fields
167  * are set according to the varargs in a manner similar to
168  * @gst_structure_new.
169  *
170  * Returns: a new #GstStructure
171  */
172 GstStructure *
173 gst_structure_new_valist (const gchar * name,
174     const gchar * firstfield, va_list varargs)
175 {
176   GstStructure *structure;
177
178   g_return_val_if_fail (name != NULL, NULL);
179
180   structure = gst_structure_empty_new (name);
181   gst_structure_set_valist (structure, firstfield, varargs);
182
183   return structure;
184 }
185
186 /**
187  * gst_structure_set_parent_refcount:
188  * @structure: a #GstStructure
189  * @refcount: a pointer to the parent's refcount
190  *
191  * Sets the parent_refcount field of #GstStructure. This field is used to
192  * determine whether a structure is mutable or not. This function should only be
193  * called by code implementing parent objects of GstStructure, as described in
194  * the MT Refcounting section of the design documents.
195  */
196 void
197 gst_structure_set_parent_refcount (GstStructure * structure, int *refcount)
198 {
199   g_return_if_fail (structure != NULL);
200
201   /* if we have a parent_refcount already, we can only clear
202    * if with a NULL refcount */
203   if (structure->parent_refcount)
204     g_return_if_fail (refcount == NULL);
205   else
206     g_return_if_fail (refcount != NULL);
207
208   structure->parent_refcount = refcount;
209 }
210
211 /**
212  * gst_structure_copy:
213  * @structure: a #GstStructure to duplicate
214  *
215  * Duplicates a #GstStructure and all its fields and values.
216  *
217  * Returns: a new #GstStructure.
218  */
219 GstStructure *
220 gst_structure_copy (const GstStructure * structure)
221 {
222   GstStructure *new_structure;
223   GstStructureField *field;
224   guint i;
225
226   g_return_val_if_fail (structure != NULL, NULL);
227
228   new_structure =
229       gst_structure_id_empty_new_with_size (structure->name,
230       structure->fields->len);
231
232   for (i = 0; i < structure->fields->len; i++) {
233     GstStructureField new_field = { 0 };
234
235     field = GST_STRUCTURE_FIELD (structure, i);
236
237     new_field.name = field->name;
238     gst_value_init_and_copy (&new_field.value, &field->value);
239     g_array_append_val (new_structure->fields, new_field);
240   }
241
242   return new_structure;
243 }
244
245 /**
246  * gst_structure_free:
247  * @structure: the #GstStructure to free
248  *
249  * Frees a #GstStructure and all its fields and values. The structure must not
250  * have a parent when this function is called.
251  */
252 void
253 gst_structure_free (GstStructure * structure)
254 {
255   GstStructureField *field;
256   guint i;
257
258   g_return_if_fail (structure != NULL);
259   g_return_if_fail (structure->parent_refcount == NULL);
260
261   for (i = 0; i < structure->fields->len; i++) {
262     field = GST_STRUCTURE_FIELD (structure, i);
263
264     if (G_IS_VALUE (&field->value)) {
265       g_value_unset (&field->value);
266     }
267   }
268   g_array_free (structure->fields, TRUE);
269 #ifdef USE_POISONING
270   memset (structure, 0xff, sizeof (GstStructure));
271 #endif
272   g_free (structure);
273 }
274
275 /**
276  * gst_structure_get_name:
277  * @structure: a #GstStructure
278  *
279  * Accessor fuction.
280  *
281  * Returns: the name of the structure.
282  */
283 const gchar *
284 gst_structure_get_name (const GstStructure * structure)
285 {
286   g_return_val_if_fail (structure != NULL, NULL);
287
288   return g_quark_to_string (structure->name);
289 }
290
291 /**
292  * gst_structure_has_name:
293  * @structure: a #GstStructure
294  * @name: structure name to check for
295  *
296  * Returns: TRUE if @name matches the name of the structure.
297  */
298 gboolean
299 gst_structure_has_name (const GstStructure * structure, const gchar * name)
300 {
301   const gchar *structure_name;
302
303   g_return_val_if_fail (structure != NULL, FALSE);
304   g_return_val_if_fail (name != NULL, FALSE);
305
306   structure_name = g_quark_to_string (structure->name);
307
308   return (structure_name && strcmp (structure_name, name) == 0);
309 }
310
311 /**
312  * gst_structure_get_name_id:
313  * @structure: a #GstStructure
314  *
315  * Accessor fuction.
316  *
317  * Returns: the quark representing the name of the structure.
318  */
319 GQuark
320 gst_structure_get_name_id (const GstStructure * structure)
321 {
322   g_return_val_if_fail (structure != NULL, 0);
323
324   return structure->name;
325 }
326
327 /**
328  * gst_structure_set_name:
329  * @structure: a #GstStructure
330  * @name: the new name of the structure
331  *
332  * Sets the name of the structure to the given name.  The string
333  * provided is copied before being used.
334  */
335 void
336 gst_structure_set_name (GstStructure * structure, const gchar * name)
337 {
338   g_return_if_fail (structure != NULL);
339   g_return_if_fail (name != NULL);
340   g_return_if_fail (IS_MUTABLE (structure));
341
342   structure->name = g_quark_from_string (name);
343 }
344
345 /**
346  * gst_structure_id_set_value:
347  * @structure: a #GstStructure
348  * @field: a #GQuark representing a field
349  * @value: the new value of the field
350  *
351  * Sets the field with the given ID to the provided value.  If the field
352  * does not exist, it is created.  If the field exists, the previous
353  * value is freed.
354  */
355 void
356 gst_structure_id_set_value (GstStructure * structure,
357     GQuark field, const GValue * value)
358 {
359   GstStructureField gsfield = { 0, {0,} };
360
361   g_return_if_fail (structure != NULL);
362   g_return_if_fail (G_IS_VALUE (value));
363   g_return_if_fail (IS_MUTABLE (structure));
364
365   gsfield.name = field;
366   gst_value_init_and_copy (&gsfield.value, value);
367
368   gst_structure_set_field (structure, &gsfield);
369 }
370
371 /**
372  * gst_structure_set_value:
373  * @structure: a #GstStructure
374  * @fieldname: the name of the field to set
375  * @value: the new value of the field
376  *
377  * Sets the field with the given name to the provided value.  If the field
378  * does not exist, it is created.  If the field exists, the previous
379  * value is freed.
380  */
381 void
382 gst_structure_set_value (GstStructure * structure,
383     const gchar * fieldname, const GValue * value)
384 {
385   g_return_if_fail (structure != NULL);
386   g_return_if_fail (fieldname != NULL);
387   g_return_if_fail (G_IS_VALUE (value));
388   g_return_if_fail (IS_MUTABLE (structure));
389
390   gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
391       value);
392 }
393
394 /**
395  * gst_structure_set:
396  * @structure: a #GstStructure
397  * @fieldname: the name of the field to set
398  * @...: variable arguments
399  *
400  * Parses the variable arguments and sets fields accordingly.
401  * Variable arguments should be in the form field name, field type
402  * (as a GType), value.  The last variable argument should be NULL.
403  */
404 void
405 gst_structure_set (GstStructure * structure, const gchar * field, ...)
406 {
407   va_list varargs;
408
409   g_return_if_fail (structure != NULL);
410
411   va_start (varargs, field);
412
413   gst_structure_set_valist (structure, field, varargs);
414
415   va_end (varargs);
416 }
417
418 /**
419  * gst_structure_set_valist:
420  * @structure: a #GstStructure
421  * @fieldname: the name of the field to set
422  * @varargs: variable arguments
423  *
424  * va_list form of #gst_structure_set.
425  */
426 void
427 gst_structure_set_valist (GstStructure * structure,
428     const gchar * fieldname, va_list varargs)
429 {
430   gchar *err = NULL;
431   GType type;
432
433   g_return_if_fail (structure != NULL);
434   g_return_if_fail (IS_MUTABLE (structure));
435
436   while (fieldname) {
437     GstStructureField field = { 0 };
438
439     field.name = g_quark_from_string (fieldname);
440
441     type = va_arg (varargs, GType);
442
443 #if GLIB_CHECK_VERSION(2,8,0)
444     if (type == G_TYPE_DATE) {
445       g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
446       type = GST_TYPE_DATE;
447     }
448 #endif
449
450     g_value_init (&field.value, type);
451     G_VALUE_COLLECT (&field.value, varargs, 0, &err);
452     if (err) {
453       g_critical ("%s", err);
454       return;
455     }
456     gst_structure_set_field (structure, &field);
457
458     fieldname = va_arg (varargs, gchar *);
459   }
460 }
461
462 /* If the structure currently contains a field with the same name, it is
463  * replaced with the provided field. Otherwise, the field is added to the
464  * structure. The field's value is not deeply copied.
465  */
466 static void
467 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
468 {
469   GstStructureField *f;
470   guint i;
471
472   for (i = 0; i < structure->fields->len; i++) {
473     f = GST_STRUCTURE_FIELD (structure, i);
474
475     if (f->name == field->name) {
476       g_value_unset (&f->value);
477       memcpy (f, field, sizeof (GstStructureField));
478       return;
479     }
480   }
481
482   g_array_append_val (structure->fields, *field);
483 }
484
485 /* If there is no field with the given ID, NULL is returned.
486  */
487 static GstStructureField *
488 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
489 {
490   GstStructureField *field;
491   guint i;
492
493   g_return_val_if_fail (structure != NULL, NULL);
494
495   for (i = 0; i < structure->fields->len; i++) {
496     field = GST_STRUCTURE_FIELD (structure, i);
497
498     if (field->name == field_id)
499       return field;
500   }
501
502   return NULL;
503 }
504
505 /* If there is no field with the given ID, NULL is returned.
506  */
507 static GstStructureField *
508 gst_structure_get_field (const GstStructure * structure,
509     const gchar * fieldname)
510 {
511   g_return_val_if_fail (structure != NULL, NULL);
512   g_return_val_if_fail (fieldname != NULL, NULL);
513
514   return gst_structure_id_get_field (structure,
515       g_quark_from_string (fieldname));
516 }
517
518 /**
519  * gst_structure_get_value:
520  * @structure: a #GstStructure
521  * @fieldname: the name of the field to get
522  *
523  * Accessor function.
524  *
525  * Returns: the #GValue corresponding to the field with the given name.
526  */
527 const GValue *
528 gst_structure_get_value (const GstStructure * structure,
529     const gchar * fieldname)
530 {
531   GstStructureField *field;
532
533   g_return_val_if_fail (structure != NULL, NULL);
534   g_return_val_if_fail (fieldname != NULL, NULL);
535
536   field = gst_structure_get_field (structure, fieldname);
537   if (field == NULL)
538     return NULL;
539
540   return &field->value;
541 }
542
543 /**
544  * gst_structure_id_get_value:
545  * @structure: a #GstStructure
546  * @field: the #GQuark of the field to get
547  *
548  * Accessor function.
549  *
550  * Returns: the #GValue corresponding to the field with the given name
551  *          identifier.
552  */
553 const GValue *
554 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
555 {
556   GstStructureField *gsfield;
557
558   g_return_val_if_fail (structure != NULL, NULL);
559
560   gsfield = gst_structure_id_get_field (structure, field);
561   if (gsfield == NULL)
562     return NULL;
563
564   return &gsfield->value;
565 }
566
567 /**
568  * gst_structure_remove_field:
569  * @structure: a #GstStructure
570  * @fieldname: the name of the field to remove
571  *
572  * Removes the field with the given name.  If the field with the given
573  * name does not exist, the structure is unchanged.
574  */
575 void
576 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
577 {
578   GstStructureField *field;
579   GQuark id;
580   guint i;
581
582   g_return_if_fail (structure != NULL);
583   g_return_if_fail (fieldname != NULL);
584   g_return_if_fail (IS_MUTABLE (structure));
585
586   id = g_quark_from_string (fieldname);
587
588   for (i = 0; i < structure->fields->len; i++) {
589     field = GST_STRUCTURE_FIELD (structure, i);
590
591     if (field->name == id) {
592       if (G_IS_VALUE (&field->value)) {
593         g_value_unset (&field->value);
594       }
595       structure->fields = g_array_remove_index (structure->fields, i);
596       return;
597     }
598   }
599 }
600
601 /**
602  * gst_structure_remove_fields:
603  * @structure: a #GstStructure
604  * @fieldname: the name of the field to remove
605  * @...: NULL-terminated list of more fieldnames to remove
606  *
607  * Removes the field with the given names. If a field does not exist, the
608  * argument is ignored.
609  */
610 void
611 gst_structure_remove_fields (GstStructure * structure,
612     const gchar * fieldname, ...)
613 {
614   va_list varargs;
615
616   g_return_if_fail (structure != NULL);
617   g_return_if_fail (fieldname != NULL);
618   /* mutability checked in remove_field */
619
620   va_start (varargs, fieldname);
621
622   gst_structure_remove_fields_valist (structure, fieldname, varargs);
623
624   va_end (varargs);
625 }
626
627 /**
628  * gst_structure_remove_fields_valist:
629  * @structure: a #GstStructure
630  * @fieldname: the name of the field to remove
631  * @varargs: NULL-terminated list of more fieldnames to remove
632  *
633  * Removes the field with the given names. If a field does not exist, the
634  * argument is ignored.
635  */
636 void
637 gst_structure_remove_fields_valist (GstStructure * structure,
638     const gchar * fieldname, va_list varargs)
639 {
640   gchar *field = (gchar *) fieldname;
641
642   g_return_if_fail (structure != NULL);
643   g_return_if_fail (fieldname != NULL);
644   /* mutability checked in remove_field */
645
646   while (field) {
647     gst_structure_remove_field (structure, field);
648     field = va_arg (varargs, char *);
649   }
650 }
651
652 /**
653  * gst_structure_remove_all_fields:
654  * @structure: a #GstStructure
655  *
656  * Removes all fields in a GstStructure.
657  */
658 void
659 gst_structure_remove_all_fields (GstStructure * structure)
660 {
661   GstStructureField *field;
662   int i;
663
664   g_return_if_fail (structure != NULL);
665   g_return_if_fail (IS_MUTABLE (structure));
666
667   for (i = structure->fields->len - 1; i >= 0; i--) {
668     field = GST_STRUCTURE_FIELD (structure, i);
669
670     if (G_IS_VALUE (&field->value)) {
671       g_value_unset (&field->value);
672     }
673     structure->fields = g_array_remove_index (structure->fields, i);
674   }
675 }
676
677 /**
678  * gst_structure_get_field_type:
679  * @structure: a #GstStructure
680  * @fieldname: the name of the field
681  *
682  * Finds the field with the given name, and returns the type of the
683  * value it contains.  If the field is not found, G_TYPE_INVALID is
684  * returned.
685  *
686  * Returns: the #GValue of the field
687  */
688 GType
689 gst_structure_get_field_type (const GstStructure * structure,
690     const gchar * fieldname)
691 {
692   GstStructureField *field;
693
694   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
695   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
696
697   field = gst_structure_get_field (structure, fieldname);
698   if (field == NULL)
699     return G_TYPE_INVALID;
700
701   return G_VALUE_TYPE (&field->value);
702 }
703
704 /**
705  * gst_structure_n_fields:
706  * @structure: a #GstStructure
707  *
708  * Accessor function.
709  *
710  * Returns: the number of fields in the structure
711  */
712 gint
713 gst_structure_n_fields (const GstStructure * structure)
714 {
715   g_return_val_if_fail (structure != NULL, 0);
716
717   return structure->fields->len;
718 }
719
720 /**
721  * gst_structure_nth_field_name:
722  * @structure: a #GstStructure
723  * @index: the index to get the name of
724  *
725  * Returns: the name of the given field number, counting from 0 onwards.
726  */
727 const gchar *
728 gst_structure_nth_field_name (const GstStructure * structure, guint index)
729 {
730   GstStructureField *field;
731
732   field = GST_STRUCTURE_FIELD (structure, index);
733   return g_quark_to_string (field->name);
734 }
735
736 /**
737  * gst_structure_foreach:
738  * @structure: a #GstStructure
739  * @func: a function to call for each field
740  * @user_data: private data
741  *
742  * Calls the provided function once for each field in the #GstStructure. The
743  * function must not modify the fields. Also see gst_structure_map_in_place().
744  *
745  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
746  * FALSE otherwise.
747  */
748 gboolean
749 gst_structure_foreach (const GstStructure * structure,
750     GstStructureForeachFunc func, gpointer user_data)
751 {
752   guint i;
753   GstStructureField *field;
754   gboolean ret;
755
756   g_return_val_if_fail (structure != NULL, FALSE);
757
758   for (i = 0; i < structure->fields->len; i++) {
759     field = GST_STRUCTURE_FIELD (structure, i);
760
761     ret = func (field->name, &field->value, user_data);
762     if (!ret)
763       return FALSE;
764   }
765
766   return TRUE;
767 }
768
769 /**
770  * gst_structure_map_in_place:
771  * @structure: a #GstStructure
772  * @func: a function to call for each field
773  * @user_data: private data
774  *
775  * Calls the provided function once for each field in the #GstStructure. In
776  * contrast to gst_structure_foreach(), the function may modify the fields. The
777  * structure must be mutable.
778  *
779  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
780  * FALSE otherwise.
781  */
782 gboolean
783 gst_structure_map_in_place (GstStructure * structure,
784     GstStructureMapFunc func, gpointer user_data)
785 {
786   guint i;
787   GstStructureField *field;
788   gboolean ret;
789
790   g_return_val_if_fail (structure != NULL, FALSE);
791   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
792
793   for (i = 0; i < structure->fields->len; i++) {
794     field = GST_STRUCTURE_FIELD (structure, i);
795
796     ret = func (field->name, &field->value, user_data);
797     if (!ret)
798       return FALSE;
799   }
800
801   return TRUE;
802 }
803
804 /**
805  * gst_structure_has_field:
806  * @structure: a #GstStructure
807  * @fieldname: the name of a field
808  *
809  * Accessor function.
810  *
811  * Returns: TRUE if the structure contains a field with the given name
812  */
813 gboolean
814 gst_structure_has_field (const GstStructure * structure,
815     const gchar * fieldname)
816 {
817   GstStructureField *field;
818
819   g_return_val_if_fail (structure != NULL, 0);
820   g_return_val_if_fail (fieldname != NULL, 0);
821
822   field = gst_structure_get_field (structure, fieldname);
823
824   return (field != NULL);
825 }
826
827 /**
828  * gst_structure_has_field_typed:
829  * @structure: a #GstStructure
830  * @fieldname: the name of a field
831  * @type: the type of a value
832  *
833  * Accessor function.
834  *
835  * Returns: TRUE if the structure contains a field with the given name and type
836  */
837 gboolean
838 gst_structure_has_field_typed (const GstStructure * structure,
839     const gchar * fieldname, GType type)
840 {
841   GstStructureField *field;
842
843   g_return_val_if_fail (structure != NULL, 0);
844   g_return_val_if_fail (fieldname != NULL, 0);
845
846   field = gst_structure_get_field (structure, fieldname);
847   if (field == NULL)
848     return FALSE;
849
850   return (G_VALUE_TYPE (&field->value) == type);
851 }
852
853
854 /* utility functions */
855
856 /**
857  * gst_structure_get_boolean:
858  * @structure: a #GstStructure
859  * @fieldname: the name of a field
860  * @value: a pointer to a #gboolean to set
861  *
862  * Sets the boolean pointed to by @value corresponding to the value of the
863  * given field.  Caller is responsible for making sure the field exists
864  * and has the correct type.
865  *
866  * Returns: TRUE if the value could be set correctly
867  */
868 gboolean
869 gst_structure_get_boolean (const GstStructure * structure,
870     const gchar * fieldname, gboolean * value)
871 {
872   GstStructureField *field;
873
874   g_return_val_if_fail (structure != NULL, FALSE);
875   g_return_val_if_fail (fieldname != NULL, FALSE);
876
877   field = gst_structure_get_field (structure, fieldname);
878
879   if (field == NULL)
880     return FALSE;
881   if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
882     return FALSE;
883
884   *value = g_value_get_boolean (&field->value);
885
886   return TRUE;
887 }
888
889 /**
890  * gst_structure_get_int:
891  * @structure: a #GstStructure
892  * @fieldname: the name of a field
893  * @value: a pointer to an int to set
894  *
895  * Sets the int pointed to by @value corresponding to the value of the
896  * given field.  Caller is responsible for making sure the field exists
897  * and has the correct type.
898  *
899  * Returns: TRUE if the value could be set correctly
900  */
901 gboolean
902 gst_structure_get_int (const GstStructure * structure,
903     const gchar * fieldname, gint * value)
904 {
905   GstStructureField *field;
906
907   g_return_val_if_fail (structure != NULL, FALSE);
908   g_return_val_if_fail (fieldname != NULL, FALSE);
909   g_return_val_if_fail (value != NULL, FALSE);
910
911   field = gst_structure_get_field (structure, fieldname);
912
913   if (field == NULL)
914     return FALSE;
915   if (!G_VALUE_HOLDS_INT (&field->value))
916     return FALSE;
917
918   *value = g_value_get_int (&field->value);
919
920   return TRUE;
921 }
922
923 /**
924  * gst_structure_get_fourcc:
925  * @structure: a #GstStructure
926  * @fieldname: the name of a field
927  * @value: a pointer to a #GstFourcc to set
928  *
929  * Sets the #GstFourcc pointed to by @value corresponding to the value of the
930  * given field.  Caller is responsible for making sure the field exists
931  * and has the correct type.
932  *
933  * Returns: TRUE if the value could be set correctly
934  */
935 gboolean
936 gst_structure_get_fourcc (const GstStructure * structure,
937     const gchar * fieldname, guint32 * value)
938 {
939   GstStructureField *field;
940
941   g_return_val_if_fail (structure != NULL, FALSE);
942   g_return_val_if_fail (fieldname != NULL, FALSE);
943   g_return_val_if_fail (value != NULL, FALSE);
944
945   field = gst_structure_get_field (structure, fieldname);
946
947   if (field == NULL)
948     return FALSE;
949   if (!GST_VALUE_HOLDS_FOURCC (&field->value))
950     return FALSE;
951
952   *value = gst_value_get_fourcc (&field->value);
953
954   return TRUE;
955 }
956
957 /**
958  * gst_structure_get_date:
959  * @structure: a #GstStructure
960  * @fieldname: the name of a field
961  * @value: a pointer to a #GDate to set
962  *
963  * Sets the date pointed to by @value corresponding to the date of the
964  * given field.  Caller is responsible for making sure the field exists
965  * and has the correct type.
966  *
967  * Returns: TRUE if the value could be set correctly
968  */
969 gboolean
970 gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
971     GDate ** value)
972 {
973   GstStructureField *field;
974
975   g_return_val_if_fail (structure != NULL, FALSE);
976   g_return_val_if_fail (fieldname != NULL, FALSE);
977   g_return_val_if_fail (value != NULL, FALSE);
978
979   field = gst_structure_get_field (structure, fieldname);
980
981   if (field == NULL)
982     return FALSE;
983   if (!GST_VALUE_HOLDS_DATE (&field->value))
984     return FALSE;
985
986   *value = g_value_dup_boxed (&field->value);
987
988   return TRUE;
989 }
990
991 /**
992  * gst_structure_get_clock_time:
993  * @structure: a #GstStructure
994  * @fieldname: the name of a field
995  * @value: a pointer to a #GstClockTime to set
996  *
997  * Sets the clock time pointed to by @value corresponding to the clock time
998  * of the given field.  Caller is responsible for making sure the field exists
999  * and has the correct type.
1000  *
1001  * Returns: TRUE if the value could be set correctly
1002  */
1003 gboolean
1004 gst_structure_get_clock_time (const GstStructure * structure,
1005     const gchar * fieldname, GstClockTime * value)
1006 {
1007   GstStructureField *field;
1008
1009   g_return_val_if_fail (structure != NULL, FALSE);
1010   g_return_val_if_fail (fieldname != NULL, FALSE);
1011   g_return_val_if_fail (value != NULL, FALSE);
1012
1013   field = gst_structure_get_field (structure, fieldname);
1014
1015   if (field == NULL)
1016     return FALSE;
1017   if (!G_VALUE_HOLDS_UINT64 (&field->value))
1018     return FALSE;
1019
1020   *value = g_value_get_uint64 (&field->value);
1021
1022   return TRUE;
1023 }
1024
1025 /**
1026  * gst_structure_get_double:
1027  * @structure: a #GstStructure
1028  * @fieldname: the name of a field
1029  * @value: a pointer to a #GstFourcc to set
1030  *
1031  * Sets the double pointed to by @value corresponding to the value of the
1032  * given field.  Caller is responsible for making sure the field exists
1033  * and has the correct type.
1034  *
1035  * Returns: TRUE if the value could be set correctly
1036  */
1037 gboolean
1038 gst_structure_get_double (const GstStructure * structure,
1039     const gchar * fieldname, gdouble * value)
1040 {
1041   GstStructureField *field;
1042
1043   g_return_val_if_fail (structure != NULL, FALSE);
1044   g_return_val_if_fail (fieldname != NULL, FALSE);
1045   g_return_val_if_fail (value != NULL, FALSE);
1046
1047   field = gst_structure_get_field (structure, fieldname);
1048
1049   if (field == NULL)
1050     return FALSE;
1051   if (!G_VALUE_HOLDS_DOUBLE (&field->value))
1052     return FALSE;
1053
1054   *value = g_value_get_double (&field->value);
1055
1056   return TRUE;
1057 }
1058
1059 /**
1060  * gst_structure_get_string:
1061  * @structure: a #GstStructure
1062  * @fieldname: the name of a field
1063  *
1064  * Finds the field corresponding to @fieldname, and returns the string
1065  * contained in the field's value.  Caller is responsible for making
1066  * sure the field exists and has the correct type.
1067  *
1068  * The string should not be modified, and remains valid until the next
1069  * call to a gst_structure_*() function with the given structure.
1070  *
1071  * Returns: a pointer to the string
1072  */
1073 const gchar *
1074 gst_structure_get_string (const GstStructure * structure,
1075     const gchar * fieldname)
1076 {
1077   GstStructureField *field;
1078
1079   g_return_val_if_fail (structure != NULL, NULL);
1080   g_return_val_if_fail (fieldname != NULL, NULL);
1081
1082   field = gst_structure_get_field (structure, fieldname);
1083
1084   if (field == NULL)
1085     return NULL;
1086   if (!G_VALUE_HOLDS_STRING (&field->value))
1087     return NULL;
1088
1089   return g_value_get_string (&field->value);
1090 }
1091
1092 /**
1093  * gst_structure_get_enum:
1094  * @structure: a #GstStructure
1095  * @fieldname: the name of a field
1096  * @enumtype: the enum type of a field
1097  * @value: a pointer to an int to set
1098  *
1099  * Sets the int pointed to by @value corresponding to the value of the
1100  * given field.  Caller is responsible for making sure the field exists,
1101  * has the correct type and that the enumtype is correct.
1102  *
1103  * Returns: TRUE if the value could be set correctly
1104  */
1105 gboolean
1106 gst_structure_get_enum (const GstStructure * structure,
1107     const gchar * fieldname, GType enumtype, gint * value)
1108 {
1109   GstStructureField *field;
1110
1111   g_return_val_if_fail (structure != NULL, FALSE);
1112   g_return_val_if_fail (fieldname != NULL, FALSE);
1113   g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
1114   g_return_val_if_fail (value != NULL, FALSE);
1115
1116   field = gst_structure_get_field (structure, fieldname);
1117
1118   if (field == NULL)
1119     return FALSE;
1120   if (!G_VALUE_HOLDS_ENUM (&field->value))
1121     return FALSE;
1122   if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
1123     return FALSE;
1124
1125   *value = g_value_get_enum (&field->value);
1126
1127   return TRUE;
1128 }
1129
1130 typedef struct _GstStructureAbbreviation
1131 {
1132   char *type_name;
1133   GType type;
1134 }
1135 GstStructureAbbreviation;
1136
1137 static GstStructureAbbreviation *
1138 gst_structure_get_abbrs (gint * n_abbrs)
1139 {
1140   static GstStructureAbbreviation *abbrs = NULL;
1141   static gint num = 0;
1142
1143   if (abbrs == NULL) {
1144     /* dynamically generate the array */
1145     GstStructureAbbreviation dyn_abbrs[] = {
1146       {"int", G_TYPE_INT}
1147       ,
1148       {"i", G_TYPE_INT}
1149       ,
1150       {"float", G_TYPE_FLOAT}
1151       ,
1152       {"f", G_TYPE_FLOAT}
1153       ,
1154       {"double", G_TYPE_DOUBLE}
1155       ,
1156       {"d", G_TYPE_DOUBLE}
1157       ,
1158       {"buffer", GST_TYPE_BUFFER}
1159       ,
1160       {"fourcc", GST_TYPE_FOURCC}
1161       ,
1162       {"4", GST_TYPE_FOURCC}
1163       ,
1164       {"fraction", GST_TYPE_FRACTION}
1165       ,
1166       {"boolean", G_TYPE_BOOLEAN}
1167       ,
1168       {"bool", G_TYPE_BOOLEAN}
1169       ,
1170       {"b", G_TYPE_BOOLEAN}
1171       ,
1172       {"string", G_TYPE_STRING}
1173       ,
1174       {"str", G_TYPE_STRING}
1175       ,
1176       {"s", G_TYPE_STRING}
1177     };
1178     num = G_N_ELEMENTS (dyn_abbrs);
1179     /* permanently allocate and copy the array now */
1180     abbrs = g_new0 (GstStructureAbbreviation, num);
1181     memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num);
1182   }
1183   *n_abbrs = num;
1184
1185   return abbrs;
1186 }
1187
1188 static GType
1189 gst_structure_from_abbr (const char *type_name)
1190 {
1191   int i;
1192   GstStructureAbbreviation *abbrs;
1193   gint n_abbrs;
1194
1195   g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1196
1197   abbrs = gst_structure_get_abbrs (&n_abbrs);
1198
1199   for (i = 0; i < n_abbrs; i++) {
1200     if (strcmp (type_name, abbrs[i].type_name) == 0) {
1201       return abbrs[i].type;
1202     }
1203   }
1204
1205   /* this is the fallback */
1206   return g_type_from_name (type_name);
1207 }
1208
1209 static const char *
1210 gst_structure_to_abbr (GType type)
1211 {
1212   int i;
1213   GstStructureAbbreviation *abbrs;
1214   gint n_abbrs;
1215
1216   g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1217
1218   abbrs = gst_structure_get_abbrs (&n_abbrs);
1219
1220   for (i = 0; i < n_abbrs; i++) {
1221     if (type == abbrs[i].type) {
1222       return abbrs[i].type_name;
1223     }
1224   }
1225
1226   return g_type_name (type);
1227 }
1228
1229 static GType
1230 gst_structure_value_get_generic_type (GValue * val)
1231 {
1232   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1233       || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1234     GArray *array = g_value_peek_pointer (val);
1235
1236     if (array->len > 0) {
1237       GValue *value = &g_array_index (array, GValue, 0);
1238
1239       return gst_structure_value_get_generic_type (value);
1240     } else {
1241       return G_TYPE_INT;
1242     }
1243   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1244     return G_TYPE_INT;
1245   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1246     return G_TYPE_DOUBLE;
1247   }
1248   return G_VALUE_TYPE (val);
1249 }
1250
1251 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1252       ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1253       ((c) == '.'))
1254
1255 /**
1256  * gst_structure_to_string:
1257  * @structure: a #GstStructure
1258  *
1259  * Converts @structure to a human-readable representation.
1260  *
1261  * Returns: a pointer to string allocated by g_malloc()
1262  */
1263 gchar *
1264 gst_structure_to_string (const GstStructure * structure)
1265 {
1266   GstStructureField *field;
1267   GString *s;
1268   guint i;
1269
1270   /* NOTE:  This function is potentially called by the debug system,
1271    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1272    * should be careful to avoid recursion.  This includes any functions
1273    * called by gst_structure_to_string.  In particular, calls should
1274    * not use the GST_PTR_FORMAT extension.  */
1275
1276   g_return_val_if_fail (structure != NULL, NULL);
1277
1278   s = g_string_new ("");
1279   /* FIXME this string may need to be escaped */
1280   g_string_append_printf (s, "%s", g_quark_to_string (structure->name));
1281   for (i = 0; i < structure->fields->len; i++) {
1282     char *t;
1283     GType type;
1284
1285     field = GST_STRUCTURE_FIELD (structure, i);
1286
1287     t = gst_value_serialize (&field->value);
1288     type = gst_structure_value_get_generic_type (&field->value);
1289
1290     g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name),
1291         gst_structure_to_abbr (type), GST_STR_NULL (t));
1292     g_free (t);
1293   }
1294   return g_string_free (s, FALSE);
1295 }
1296
1297 /*
1298  * r will still point to the string. if end == next, the string will not be
1299  * null-terminated. In all other cases it will be.
1300  * end = pointer to char behind end of string, next = pointer to start of
1301  * unread data.
1302  * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1303  */
1304 static gboolean
1305 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1306 {
1307   gchar *w;
1308
1309   if (*s == 0)
1310     return FALSE;
1311
1312   if (*s != '"') {
1313     int ret;
1314
1315     ret = gst_structure_parse_simple_string (s, end);
1316     *next = *end;
1317
1318     return ret;
1319   }
1320
1321   w = s;
1322   s++;
1323   while (*s != '"') {
1324     if (*s == 0)
1325       return FALSE;
1326
1327     if (*s == '\\') {
1328       s++;
1329     }
1330
1331     *w = *s;
1332     w++;
1333     s++;
1334   }
1335   s++;
1336
1337   *end = w;
1338   *next = s;
1339
1340   return TRUE;
1341 }
1342
1343 static gboolean
1344 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1345     GType type)
1346 {
1347   GValue value1 = { 0 };
1348   GValue value2 = { 0 };
1349   GType range_type;
1350   gboolean ret;
1351
1352
1353   if (*s != '[')
1354     return FALSE;
1355   s++;
1356
1357   ret = gst_structure_parse_value (s, &s, &value1, type);
1358   if (ret == FALSE)
1359     return FALSE;
1360
1361   while (g_ascii_isspace (*s))
1362     s++;
1363
1364   if (*s != ',')
1365     return FALSE;
1366   s++;
1367
1368   while (g_ascii_isspace (*s))
1369     s++;
1370
1371   ret = gst_structure_parse_value (s, &s, &value2, type);
1372   if (ret == FALSE)
1373     return FALSE;
1374
1375   while (g_ascii_isspace (*s))
1376     s++;
1377
1378   if (*s != ']')
1379     return FALSE;
1380   s++;
1381
1382   if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1383     return FALSE;
1384
1385   if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1386     range_type = GST_TYPE_DOUBLE_RANGE;
1387   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1388     range_type = GST_TYPE_INT_RANGE;
1389   } else {
1390     return FALSE;
1391   }
1392
1393   g_value_init (value, range_type);
1394   if (range_type == GST_TYPE_DOUBLE_RANGE) {
1395     gst_value_set_double_range (value, g_value_get_double (&value1),
1396         g_value_get_double (&value2));
1397   } else {
1398     gst_value_set_int_range (value, g_value_get_int (&value1),
1399         g_value_get_int (&value2));
1400   }
1401
1402   *after = s;
1403   return TRUE;
1404 }
1405
1406 static gboolean
1407 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1408     GType type, GType list_type, char begin, char end)
1409 {
1410   GValue list_value = { 0 };
1411   gboolean ret;
1412   GArray *array;
1413
1414   g_value_init (value, list_type);
1415   array = g_value_peek_pointer (value);
1416
1417   if (*s != begin)
1418     return FALSE;
1419   s++;
1420
1421   while (g_ascii_isspace (*s))
1422     s++;
1423   if (*s == end) {
1424     s++;
1425     *after = s;
1426     return TRUE;
1427   }
1428
1429   ret = gst_structure_parse_value (s, &s, &list_value, type);
1430   if (ret == FALSE)
1431     return FALSE;
1432
1433   g_array_append_val (array, list_value);
1434
1435   while (g_ascii_isspace (*s))
1436     s++;
1437
1438   while (*s != end) {
1439     if (*s != ',')
1440       return FALSE;
1441     s++;
1442
1443     while (g_ascii_isspace (*s))
1444       s++;
1445
1446     memset (&list_value, 0, sizeof (list_value));
1447     ret = gst_structure_parse_value (s, &s, &list_value, type);
1448     if (ret == FALSE)
1449       return FALSE;
1450
1451     g_array_append_val (array, list_value);
1452     while (g_ascii_isspace (*s))
1453       s++;
1454   }
1455
1456   s++;
1457
1458   *after = s;
1459   return TRUE;
1460 }
1461
1462 static gboolean
1463 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1464 {
1465   return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1466       '{', '}');
1467 }
1468
1469 static gboolean
1470 gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
1471     GType type)
1472 {
1473   return gst_structure_parse_any_list (s, after, value, type,
1474       GST_TYPE_ARRAY, '<', '>');
1475 }
1476
1477 static gboolean
1478 gst_structure_parse_simple_string (gchar * str, gchar ** end)
1479 {
1480   char *s = str;
1481
1482   while (GST_ASCII_IS_STRING (*s)) {
1483     s++;
1484   }
1485
1486   *end = s;
1487
1488   return (s != str);
1489 }
1490
1491 static gboolean
1492 gst_structure_parse_field (gchar * str,
1493     gchar ** after, GstStructureField * field)
1494 {
1495   gchar *name;
1496   gchar *name_end;
1497   gchar *s;
1498   gchar c;
1499
1500   s = str;
1501
1502   while (g_ascii_isspace (*s))
1503     s++;
1504   name = s;
1505   if (!gst_structure_parse_simple_string (s, &name_end))
1506     return FALSE;
1507
1508   s = name_end;
1509   while (g_ascii_isspace (*s))
1510     s++;
1511
1512   if (*s != '=')
1513     return FALSE;
1514   s++;
1515
1516   c = *name_end;
1517   *name_end = 0;
1518   field->name = g_quark_from_string (name);
1519   *name_end = c;
1520
1521   if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1522     return FALSE;
1523
1524   *after = s;
1525   return TRUE;
1526 }
1527
1528 static gboolean
1529 gst_structure_parse_value (gchar * str,
1530     gchar ** after, GValue * value, GType default_type)
1531 {
1532   gchar *type_name;
1533   gchar *type_end;
1534   gchar *value_s;
1535   gchar *value_end;
1536   gchar *s;
1537   gchar c;
1538   int ret = 0;
1539   GType type = default_type;
1540
1541
1542   s = str;
1543   while (g_ascii_isspace (*s))
1544     s++;
1545
1546   type_name = NULL;
1547   if (*s == '(') {
1548     type = G_TYPE_INVALID;
1549
1550     s++;
1551     while (g_ascii_isspace (*s))
1552       s++;
1553     type_name = s;
1554     if (!gst_structure_parse_simple_string (s, &type_end))
1555       return FALSE;
1556     s = type_end;
1557     while (g_ascii_isspace (*s))
1558       s++;
1559     if (*s != ')')
1560       return FALSE;
1561     s++;
1562     while (g_ascii_isspace (*s))
1563       s++;
1564
1565     c = *type_end;
1566     *type_end = 0;
1567     type = gst_structure_from_abbr (type_name);
1568     *type_end = c;
1569
1570     if (type == G_TYPE_INVALID)
1571       return FALSE;
1572   }
1573
1574   while (g_ascii_isspace (*s))
1575     s++;
1576   if (*s == '[') {
1577     ret = gst_structure_parse_range (s, &s, value, type);
1578   } else if (*s == '{') {
1579     ret = gst_structure_parse_list (s, &s, value, type);
1580   } else if (*s == '<') {
1581     ret = gst_structure_parse_array (s, &s, value, type);
1582   } else {
1583     value_s = s;
1584     if (!gst_structure_parse_string (s, &value_end, &s))
1585       return FALSE;
1586
1587     c = *value_end;
1588     *value_end = 0;
1589     if (type == G_TYPE_INVALID) {
1590       GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1591       int i;
1592
1593       for (i = 0; i < 3; i++) {
1594         g_value_init (value, try_types[i]);
1595         ret = gst_value_deserialize (value, value_s);
1596         if (ret)
1597           break;
1598         g_value_unset (value);
1599       }
1600     } else {
1601       g_value_init (value, type);
1602
1603       ret = gst_value_deserialize (value, value_s);
1604     }
1605     *value_end = c;
1606   }
1607
1608   *after = s;
1609
1610   return ret;
1611 }
1612
1613 /**
1614  * gst_structure_from_string:
1615  * @string: a string representation of a #GstStructure.
1616  * @end: pointer to store the end of the string in.
1617  *
1618  * Creates a #GstStructure from a string representation.
1619  * If end is not NULL, a pointer to the place inside the given string
1620  * where parsing ended will be returned.
1621  *
1622  * Returns: a new #GstStructure
1623  */
1624 GstStructure *
1625 gst_structure_from_string (const gchar * string, gchar ** end)
1626 {
1627   char *name;
1628   char *copy;
1629   char *w;
1630   char *r;
1631   char save;
1632   GstStructure *structure = NULL;
1633   GstStructureField field = { 0 };
1634
1635   g_return_val_if_fail (string != NULL, NULL);
1636
1637   copy = g_strdup (string);
1638   r = copy;
1639
1640   name = r;
1641   if (!gst_structure_parse_string (r, &w, &r))
1642     goto error;
1643
1644   while (g_ascii_isspace (*r))
1645     r++;
1646   if (*r != 0 && *r != ';' && *r != ',')
1647     goto error;
1648
1649   save = *w;
1650   *w = 0;
1651   structure = gst_structure_empty_new (name);
1652   *w = save;
1653
1654   while (*r && (*r != ';')) {
1655     if (*r != ',')
1656       goto error;
1657     r++;
1658     while (*r && g_ascii_isspace (*r))
1659       r++;
1660
1661     memset (&field, 0, sizeof (field));
1662     if (!gst_structure_parse_field (r, &r, &field))
1663       goto error;
1664     gst_structure_set_field (structure, &field);
1665     while (*r && g_ascii_isspace (*r))
1666       r++;
1667   }
1668
1669   if (end)
1670     *end = (char *) string + (r - copy);
1671
1672   g_free (copy);
1673   return structure;
1674
1675 error:
1676   if (structure)
1677     gst_structure_free (structure);
1678   g_free (copy);
1679   return NULL;
1680 }
1681
1682 static void
1683 gst_structure_transform_to_string (const GValue * src_value,
1684     GValue * dest_value)
1685 {
1686   g_return_if_fail (src_value != NULL);
1687   g_return_if_fail (dest_value != NULL);
1688
1689   dest_value->data[0].v_pointer =
1690       gst_structure_to_string (src_value->data[0].v_pointer);
1691 }
1692
1693 static GstStructure *
1694 gst_structure_copy_conditional (const GstStructure * structure)
1695 {
1696   if (structure)
1697     return gst_structure_copy (structure);
1698   return NULL;
1699 }
1700
1701 /* fixate utility functions */
1702
1703 /**
1704  * gst_caps_structure_fixate_field_nearest_int:
1705  * @structure: a #GstStructure
1706  * @field_name: a field in @structure
1707  * @target: the target value of the fixation
1708  *
1709  * Fixates a #GstStructure by changing the given field to the nearest
1710  * integer to @target that is a subset of the existing field.
1711  *
1712  * Returns: TRUE if the structure could be fixated
1713  */
1714 /* FIXME: rename to gst_structure_... */
1715 gboolean
1716 gst_caps_structure_fixate_field_nearest_int (GstStructure * structure,
1717     const char *field_name, int target)
1718 {
1719   const GValue *value;
1720
1721   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1722   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1723
1724   value = gst_structure_get_value (structure, field_name);
1725
1726   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
1727     /* already fixed */
1728     return FALSE;
1729   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
1730     int x;
1731
1732     x = gst_value_get_int_range_min (value);
1733     if (target < x)
1734       target = x;
1735     x = gst_value_get_int_range_max (value);
1736     if (target > x)
1737       target = x;
1738     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
1739     return TRUE;
1740   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1741     const GValue *list_value;
1742     int i, n;
1743     int best = 0;
1744     int best_index = -1;
1745
1746     n = gst_value_list_get_size (value);
1747     for (i = 0; i < n; i++) {
1748       list_value = gst_value_list_get_value (value, i);
1749       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
1750         int x = g_value_get_int (list_value);
1751
1752         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1753           best_index = i;
1754           best = x;
1755         }
1756       }
1757     }
1758     if (best_index != -1) {
1759       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
1760       return TRUE;
1761     }
1762     return FALSE;
1763   }
1764
1765   return FALSE;
1766 }
1767
1768 /**
1769  * gst_caps_structure_fixate_field_nearest_double:
1770  * @structure: a #GstStructure
1771  * @field_name: a field in @structure
1772  * @target: the target value of the fixation
1773  *
1774  * Fixates a #GstStructure by changing the given field to the nearest
1775  * double to @target that is a subset of the existing field.
1776  *
1777  * Returns: TRUE if the structure could be fixated
1778  */
1779 gboolean
1780 gst_caps_structure_fixate_field_nearest_double (GstStructure * structure,
1781     const char *field_name, double target)
1782 {
1783   const GValue *value;
1784
1785   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1786   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1787
1788   value = gst_structure_get_value (structure, field_name);
1789
1790   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
1791     /* already fixed */
1792     return FALSE;
1793   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
1794     double x;
1795
1796     x = gst_value_get_double_range_min (value);
1797     if (target < x)
1798       target = x;
1799     x = gst_value_get_double_range_max (value);
1800     if (target > x)
1801       target = x;
1802     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
1803     return TRUE;
1804   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1805     const GValue *list_value;
1806     int i, n;
1807     double best = 0;
1808     int best_index = -1;
1809
1810     n = gst_value_list_get_size (value);
1811     for (i = 0; i < n; i++) {
1812       list_value = gst_value_list_get_value (value, i);
1813       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
1814         double x = g_value_get_double (list_value);
1815
1816         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1817           best_index = i;
1818           best = x;
1819         }
1820       }
1821     }
1822     if (best_index != -1) {
1823       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
1824       return TRUE;
1825     }
1826     return FALSE;
1827   }
1828
1829   return FALSE;
1830
1831 }
1832
1833 /**
1834  * gst_caps_structure_fixate_field_boolean:
1835  * @structure: a #GstStructure
1836  * @field_name: a field in @structure
1837  * @target: the target value of the fixation
1838  *
1839  * Fixates a #GstStructure by changing the given @field_name field to the given
1840  * @target boolean if that field is not fixed yet.
1841  *
1842  * Returns: TRUE if the structure could be fixated
1843  */
1844 /* FIXME: rename to gst_structure_... */
1845 gboolean
1846 gst_caps_structure_fixate_field_boolean (GstStructure * structure,
1847     const char *field_name, gboolean target)
1848 {
1849   const GValue *value;
1850
1851   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1852   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1853
1854   value = gst_structure_get_value (structure, field_name);
1855
1856   if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
1857     /* already fixed */
1858     return FALSE;
1859   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1860     const GValue *list_value;
1861     int i, n;
1862     int best = 0;
1863     int best_index = -1;
1864
1865     n = gst_value_list_get_size (value);
1866     for (i = 0; i < n; i++) {
1867       list_value = gst_value_list_get_value (value, i);
1868       if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
1869         gboolean x = g_value_get_boolean (list_value);
1870
1871         if (best_index == -1 || x == target) {
1872           best_index = i;
1873           best = x;
1874         }
1875       }
1876     }
1877     if (best_index != -1) {
1878       gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
1879       return TRUE;
1880     }
1881     return FALSE;
1882   }
1883
1884   return FALSE;
1885 }