a2323c98602b5451f589e8bc235656cb440d75c6
[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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include "gst_private.h"
29 #include <gst/gst.h>
30 #include <gobject/gvaluecollector.h>
31
32 typedef struct _GstStructureField GstStructureField;
33
34 struct _GstStructureField
35 {
36   GQuark name;
37   GValue value;
38 };
39
40 #define GST_STRUCTURE_FIELD(structure, index) \
41     &g_array_index((structure)->fields, GstStructureField, (index))
42
43 static void gst_structure_set_field (GstStructure * structure,
44     GstStructureField * field);
45 static GstStructureField *gst_structure_get_field (const GstStructure *
46     structure, const gchar * fieldname);
47 static GstStructureField *gst_structure_id_get_field (const GstStructure *
48     structure, GQuark field);
49 static void gst_structure_transform_to_string (const GValue * src_value,
50     GValue * dest_value);
51 static GstStructure *gst_structure_copy_conditional (const GstStructure *
52     structure);
53 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
54     GValue * value, GType default_type);
55 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
56
57 GType
58 gst_structure_get_type (void)
59 {
60   static GType gst_structure_type;
61
62   if (!gst_structure_type) {
63     gst_structure_type = g_boxed_type_register_static ("GstStructure",
64         (GBoxedCopyFunc) gst_structure_copy_conditional,
65         (GBoxedFreeFunc) gst_structure_free);
66
67     g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
68         gst_structure_transform_to_string);
69   }
70
71   return gst_structure_type;
72 }
73
74 /**
75  * gst_structure_id_empty_new:
76  * @quark: name of new structure
77  *
78  * Creates a new, empty #GstStructure with the given name.
79  *
80  * Returns: a new, empty #GstStructure
81  */
82 GstStructure *
83 gst_structure_id_empty_new (GQuark quark)
84 {
85   GstStructure *structure;
86
87   g_return_val_if_fail (quark != 0, NULL);
88
89   structure = g_new0 (GstStructure, 1);
90   structure->name = quark;
91   structure->fields = g_array_new (FALSE, TRUE, sizeof (GstStructureField));
92
93   return structure;
94 }
95
96 /**
97  * gst_structure_empty_new:
98  * @name: name of new structure
99  *
100  * Creates a new, empty #GstStructure with the given name.
101  *
102  * Returns: a new, empty #GstStructure
103  */
104 GstStructure *
105 gst_structure_empty_new (const gchar * name)
106 {
107   GstStructure *structure;
108
109   g_return_val_if_fail (name != NULL, NULL);
110
111   structure = g_new0 (GstStructure, 1);
112   structure->name = g_quark_from_string (name);
113   structure->fields = g_array_new (FALSE, TRUE, sizeof (GstStructureField));
114
115   return structure;
116 }
117
118 /**
119  * gst_structure_new:
120  * @name: name of new structure
121  * @firstfield: name of first field to set
122  * @...: additional arguments
123  *
124  * Creates a new #GstStructure with the given name.  Parses the
125  * list of variable arguments and sets fields to the values listed.
126  * Variable arguments should be passed as field name, field type,
127  * and value.  Last variable argument should be NULL.
128  *
129  * Returns: a new #GstStructure
130  */
131 GstStructure *
132 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
133 {
134   GstStructure *structure;
135   va_list varargs;
136
137   g_return_val_if_fail (name != NULL, NULL);
138
139   va_start (varargs, firstfield);
140
141   structure = gst_structure_new_valist (name, firstfield, varargs);
142
143   va_end (varargs);
144
145   return structure;
146 }
147
148 /**
149  * gst_structure_new_valist:
150  * @name: name of new structure
151  * @firstfield: name of first field to set
152  * @varargs: variable argument list
153  *
154  * Creates a new #GstStructure with the given name.  Structure fields
155  * are set according to the varargs in a manner similar to
156  * @gst_structure_new.
157  *
158  * Returns: a new #GstStructure
159  */
160 GstStructure *
161 gst_structure_new_valist (const gchar * name,
162     const gchar * firstfield, va_list varargs)
163 {
164   GstStructure *structure;
165
166   g_return_val_if_fail (name != NULL, NULL);
167
168   structure = gst_structure_empty_new (name);
169   gst_structure_set_valist (structure, firstfield, varargs);
170
171   return structure;
172 }
173
174 /**
175  * gst_structure_copy:
176  * @structure: a #GstStructure to duplicate
177  *
178  * Duplicates a #GstStructure and all its fields and values.
179  *
180  * Returns: a new #GstStructure.
181  */
182 GstStructure *
183 gst_structure_copy (const GstStructure * structure)
184 {
185   GstStructure *new_structure;
186   GstStructureField *field;
187   int i;
188
189   g_return_val_if_fail (structure != NULL, NULL);
190
191   new_structure = gst_structure_empty_new (g_quark_to_string (structure->name));
192   new_structure->name = structure->name;
193
194   for (i = 0; i < structure->fields->len; i++) {
195     GstStructureField new_field = { 0 };
196
197     field = GST_STRUCTURE_FIELD (structure, i);
198
199     new_field.name = field->name;
200     gst_value_init_and_copy (&new_field.value, &field->value);
201     g_array_append_val (new_structure->fields, new_field);
202   }
203
204   return new_structure;
205 }
206
207 /**
208  * gst_structure_free: 
209  * @structure: the #GstStructure to free
210  *
211  * Frees a #GstStructure and all its fields and values.
212  */
213 void
214 gst_structure_free (GstStructure * structure)
215 {
216   GstStructureField *field;
217   int i;
218
219   g_return_if_fail (structure != NULL);
220
221   for (i = 0; i < structure->fields->len; i++) {
222     field = GST_STRUCTURE_FIELD (structure, i);
223
224     if (G_IS_VALUE (&field->value)) {
225       g_value_unset (&field->value);
226     }
227   }
228   g_array_free (structure->fields, TRUE);
229 #ifdef USE_POISONING
230   memset (structure, 0xff, sizeof (GstStructure));
231 #endif
232   g_free (structure);
233 }
234
235 /**
236  * gst_structure_get_name:
237  * @structure: a #GstStructure
238  *
239  * Accessor fuction.
240  *
241  * Returns: the name of the structure.
242  */
243 const gchar *
244 gst_structure_get_name (const GstStructure * structure)
245 {
246   g_return_val_if_fail (structure != NULL, NULL);
247
248   return g_quark_to_string (structure->name);
249 }
250
251 /**
252  * gst_structure_get_name:
253  * @structure: a #GstStructure
254  *
255  * Accessor fuction.
256  *
257  * Returns: the quark representing the name of the structure.
258  */
259 GQuark
260 gst_structure_get_name_id (const GstStructure * structure)
261 {
262   g_return_val_if_fail (structure != NULL, 0);
263
264   return structure->name;
265 }
266
267 /**
268  * gst_structure_set_name:
269  * @structure: a #GstStructure
270  * @name: the new name of the structure
271  *
272  * Sets the name of the structure to the given name.  The string
273  * provided is copied before being used.
274  */
275 void
276 gst_structure_set_name (GstStructure * structure, const gchar * name)
277 {
278   g_return_if_fail (structure != NULL);
279   g_return_if_fail (name != NULL);
280
281   structure->name = g_quark_from_string (name);
282 }
283
284 /**
285  * gst_structure_id_set_value:
286  * @structure: a #GstStructure
287  * @field: a #GQuark representing a field
288  * @value: the new value of the field
289  *
290  * Sets the field with the given ID to the provided value.  If the field
291  * does not exist, it is created.  If the field exists, the previous
292  * value is freed.
293  */
294 void
295 gst_structure_id_set_value (GstStructure * structure,
296     GQuark field, const GValue * value)
297 {
298   GstStructureField gsfield = { 0, {0,} };
299
300   g_return_if_fail (structure != NULL);
301   g_return_if_fail (G_IS_VALUE (value));
302
303   gsfield.name = field;
304   gst_value_init_and_copy (&gsfield.value, value);
305
306   gst_structure_set_field (structure, &gsfield);
307 }
308
309 /**
310  * gst_structure_set_value:
311  * @structure: a #GstStructure
312  * @fieldname: the name of the field to set
313  * @value: the new value of the field
314  *
315  * Sets the field with the given name to the provided value.  If the field
316  * does not exist, it is created.  If the field exists, the previous
317  * value is freed.
318  */
319 void
320 gst_structure_set_value (GstStructure * structure,
321     const gchar * fieldname, const GValue * value)
322 {
323   g_return_if_fail (structure != NULL);
324   g_return_if_fail (fieldname != NULL);
325   g_return_if_fail (G_IS_VALUE (value));
326
327   gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
328       value);
329 }
330
331 /**
332  * gst_structure_set:
333  * @structure: a #GstStructure
334  * @fieldname: the name of the field to set
335  * @...: variable arguments
336  *
337  * Parses the variable arguments and sets fields accordingly.
338  * Variable arguments should be in the form field name, field type
339  * (as a GType), value.  The last variable argument should be NULL.
340  */
341 void
342 gst_structure_set (GstStructure * structure, const gchar * field, ...)
343 {
344   va_list varargs;
345
346   g_return_if_fail (structure != NULL);
347
348   va_start (varargs, field);
349
350   gst_structure_set_valist (structure, field, varargs);
351
352   va_end (varargs);
353 }
354
355 /**
356  * gst_structure_set_valist:
357  * @structure: a #GstStructure
358  * @fieldname: the name of the field to set
359  * @varargs: variable arguments
360  *
361  * va_list form of #gst_structure_set.
362  */
363 void
364 gst_structure_set_valist (GstStructure * structure,
365     const gchar * fieldname, va_list varargs)
366 {
367   GType type;
368   int i;
369   double d;
370   char *s;
371
372   g_return_if_fail (structure != NULL);
373
374   while (fieldname) {
375     GstStructureField field = { 0 };
376
377     field.name = g_quark_from_string (fieldname);
378
379     type = va_arg (varargs, GType);
380
381     switch (type) {
382       case G_TYPE_INT:
383         i = va_arg (varargs, int);
384
385         g_value_init (&field.value, G_TYPE_INT);
386         g_value_set_int (&field.value, i);
387         break;
388       case G_TYPE_DOUBLE:
389         d = va_arg (varargs, double);
390
391         g_value_init (&field.value, G_TYPE_DOUBLE);
392         g_value_set_double (&field.value, d);
393         break;
394       case G_TYPE_BOOLEAN:
395         i = va_arg (varargs, int);
396
397         g_value_init (&field.value, G_TYPE_BOOLEAN);
398         g_value_set_boolean (&field.value, i);
399         break;
400       case G_TYPE_STRING:
401         s = va_arg (varargs, char *);
402
403         g_value_init (&field.value, G_TYPE_STRING);
404         g_value_set_string (&field.value, s);
405         break;
406       default:
407         if (type == GST_TYPE_FOURCC) {
408           i = va_arg (varargs, int);
409
410           g_value_init (&field.value, GST_TYPE_FOURCC);
411           gst_value_set_fourcc (&field.value, i);
412         } else if (type == GST_TYPE_INT_RANGE) {
413           int min, max;
414           min = va_arg (varargs, int);
415           max = va_arg (varargs, int);
416
417           g_value_init (&field.value, GST_TYPE_INT_RANGE);
418           gst_value_set_int_range (&field.value, min, max);
419         } else if (type == GST_TYPE_DOUBLE_RANGE) {
420           double min, max;
421           min = va_arg (varargs, double);
422           max = va_arg (varargs, double);
423
424           g_value_init (&field.value, GST_TYPE_DOUBLE_RANGE);
425           gst_value_set_double_range (&field.value, min, max);
426         } else if (type == GST_TYPE_BUFFER) {
427           GstBuffer *buffer = va_arg (varargs, GstBuffer *);
428
429           g_value_init (&field.value, GST_TYPE_BUFFER);
430           g_value_set_boxed (&field.value, buffer);
431         } else {
432           g_critical ("unimplemented vararg field type %d\n", (int) type);
433           return;
434         }
435         break;
436     }
437
438     gst_structure_set_field (structure, &field);
439
440     fieldname = va_arg (varargs, gchar *);
441   }
442 }
443
444 /**
445  * gst_structure_set_field:
446  * @structure: a #GstStructure
447  * @field: the #GstStructureField to set
448  *
449  * Sets a field in the structure.  If the structure currently contains
450  * a field with the same name, it is replaced with the provided field.
451  * Otherwise, the field is added to the structure.  The field's value
452  * is not deeply copied.
453  *
454  * This function is intended mainly for internal use.  The function
455  * #gst_structure_set() is recommended instead of this one.
456  */
457 static void
458 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
459 {
460   GstStructureField *f;
461   int i;
462
463   for (i = 0; i < structure->fields->len; i++) {
464     f = GST_STRUCTURE_FIELD (structure, i);
465
466     if (f->name == field->name) {
467       g_value_unset (&f->value);
468       memcpy (f, field, sizeof (GstStructureField));
469       return;
470     }
471   }
472
473   g_array_append_val (structure->fields, *field);
474 }
475
476 /* FIXME: is this private ? if so remove gtk-doc
477  * gst_structure_id_get_field:
478  * @structure: a #GstStructure
479  * @field_id: the GQuark of the field to get
480  *
481  * Gets the specified field from the structure.  If there is no
482  * field with the given ID, NULL is returned.
483  *
484  * Returns: the #GstStructureField with the given ID
485  */
486 static GstStructureField *
487 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
488 {
489   GstStructureField *field;
490   int i;
491
492   g_return_val_if_fail (structure != NULL, NULL);
493
494   for (i = 0; i < structure->fields->len; i++) {
495     field = GST_STRUCTURE_FIELD (structure, i);
496
497     if (field->name == field_id)
498       return field;
499   }
500
501   return NULL;
502 }
503
504 /**
505  * gst_structure_get_field:
506  * @structure: a #GstStructure
507  * @fieldname: the name of the field to get
508  *
509  * Gets the specified field from the structure.  If there is no
510  * field with the given ID, NULL is returned.
511  *
512  * Returns: the #GstStructureField with the given name
513  */
514 static GstStructureField *
515 gst_structure_get_field (const GstStructure * structure,
516     const gchar * fieldname)
517 {
518   g_return_val_if_fail (structure != NULL, NULL);
519   g_return_val_if_fail (fieldname != NULL, NULL);
520
521   return gst_structure_id_get_field (structure,
522       g_quark_from_string (fieldname));
523 }
524
525 /**
526  * gst_structure_get_value:
527  * @structure: a #GstStructure
528  * @fieldname: the name of the field to get
529  *
530  * Accessor function.
531  *
532  * Returns: the #GValue corresponding to the field with the given name.
533  */
534 const GValue *
535 gst_structure_get_value (const GstStructure * structure,
536     const gchar * fieldname)
537 {
538   GstStructureField *field;
539
540   g_return_val_if_fail (structure != NULL, NULL);
541   g_return_val_if_fail (fieldname != NULL, NULL);
542
543   field = gst_structure_get_field (structure, fieldname);
544   if (field == NULL)
545     return NULL;
546
547   return &field->value;
548 }
549
550 /**
551  * gst_structure_id_get_value:
552  * @structure: a #GstStructure
553  * @field: the #GQuark of the field to get
554  *
555  * Accessor function.
556  *
557  * Returns: the #GValue corresponding to the field with the given name 
558  *          identifier.
559  */
560 const GValue *
561 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
562 {
563   GstStructureField *gsfield;
564
565   g_return_val_if_fail (structure != NULL, NULL);
566
567   gsfield = gst_structure_id_get_field (structure, field);
568   if (gsfield == NULL)
569     return NULL;
570
571   return &gsfield->value;
572 }
573
574 /**
575  * gst_structure_remove_field:
576  * @structure: a #GstStructure
577  * @fieldname: the name of the field to remove
578  *
579  * Removes the field with the given name.  If the field with the given
580  * name does not exist, the structure is unchanged.
581  */
582 void
583 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
584 {
585   GstStructureField *field;
586   GQuark id;
587   int i;
588
589   g_return_if_fail (structure != NULL);
590   g_return_if_fail (fieldname != NULL);
591
592   id = g_quark_from_string (fieldname);
593
594   for (i = 0; i < structure->fields->len; i++) {
595     field = GST_STRUCTURE_FIELD (structure, i);
596
597     if (field->name == id) {
598       if (G_IS_VALUE (&field->value)) {
599         g_value_unset (&field->value);
600       }
601       structure->fields = g_array_remove_index (structure->fields, i);
602       return;
603     }
604   }
605 }
606
607 /**
608  * gst_structure_remove_fields:
609  * @structure: a #GstStructure
610  * @fieldname: the name of the field to remove
611  * @...: NULL-terminated list of more fieldnames to remove
612  *
613  * Removes the field with the given names. If a field does not exist, the
614  * argument is ignored.
615  */
616 void
617 gst_structure_remove_fields (GstStructure * structure,
618     const gchar * fieldname, ...)
619 {
620   va_list varargs;
621
622   g_return_if_fail (structure != NULL);
623   g_return_if_fail (fieldname != NULL);
624
625   va_start (varargs, fieldname);
626
627   gst_structure_remove_fields_valist (structure, fieldname, varargs);
628
629   va_end (varargs);
630 }
631
632 /**
633  * gst_structure_remove_fields_valist:
634  * @structure: a #GstStructure
635  * @fieldname: the name of the field to remove
636  * @varargs: NULL-terminated list of more fieldnames to remove
637  *
638  * Removes the field with the given names. If a field does not exist, the
639  * argument is ignored.
640  */
641 void
642 gst_structure_remove_fields_valist (GstStructure * structure,
643     const gchar * fieldname, va_list varargs)
644 {
645   gchar *field = (gchar *) fieldname;
646
647   g_return_if_fail (structure != NULL);
648   g_return_if_fail (fieldname != NULL);
649
650   while (field) {
651     gst_structure_remove_field (structure, field);
652     field = va_arg (varargs, char *);
653   }
654 }
655
656 /**
657  * gst_structure_remove_all_fields:
658  * @structure: a #GstStructure
659  *
660  * Removes all fields in a GstStructure. 
661  */
662 void
663 gst_structure_remove_all_fields (GstStructure * structure)
664 {
665   GstStructureField *field;
666   int i;
667
668   g_return_if_fail (structure != NULL);
669
670   for (i = structure->fields->len - 1; i >= 0; i--) {
671     field = GST_STRUCTURE_FIELD (structure, i);
672
673     if (G_IS_VALUE (&field->value)) {
674       g_value_unset (&field->value);
675     }
676     structure->fields = g_array_remove_index (structure->fields, i);
677   }
678 }
679
680 /**
681  * gst_structure_get_field_type:
682  * @structure: a #GstStructure
683  * @fieldname: the name of the field
684  *
685  * Finds the field with the given name, and returns the type of the
686  * value it contains.  If the field is not found, G_TYPE_INVALID is
687  * returned.
688  *
689  * Returns: the #GValue of the field
690  */
691 GType
692 gst_structure_get_field_type (const GstStructure * structure,
693     const gchar * fieldname)
694 {
695   GstStructureField *field;
696
697   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
698   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
699
700   field = gst_structure_get_field (structure, fieldname);
701   if (field == NULL)
702     return G_TYPE_INVALID;
703
704   return G_VALUE_TYPE (&field->value);
705 }
706
707 /**
708  * gst_structure_n_fields:
709  * @structure: a #GstStructure
710  *
711  * Accessor function.
712  *
713  * Returns: the number of fields in the structure
714  */
715 gint
716 gst_structure_n_fields (const GstStructure * structure)
717 {
718   g_return_val_if_fail (structure != NULL, 0);
719
720   return structure->fields->len;
721 }
722
723 /**
724  * gst_structure_foreach:
725  * @structure: a #GstStructure
726  * @func: a function to call for each field
727  * @user_data: private data
728  *
729  * Calls the provided function once for each field in the #GstStructure.
730  *
731  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
732  * FALSE otherwise.
733  */
734 gboolean
735 gst_structure_foreach (GstStructure * structure,
736     GstStructureForeachFunc func, gpointer user_data)
737 {
738   int i;
739   GstStructureField *field;
740   gboolean ret;
741
742   for (i = 0; i < structure->fields->len; i++) {
743     field = GST_STRUCTURE_FIELD (structure, i);
744
745     ret = func (field->name, &field->value, user_data);
746     if (!ret)
747       return FALSE;
748   }
749
750   return TRUE;
751 }
752
753 /**
754  * gst_structure_has_field:
755  * @structure: a #GstStructure
756  * @fieldname: the name of a field
757  *
758  * Accessor function.
759  *
760  * Returns: TRUE if the structure contains a field with the given name
761  */
762 gboolean
763 gst_structure_has_field (const GstStructure * structure,
764     const gchar * fieldname)
765 {
766   GstStructureField *field;
767
768   g_return_val_if_fail (structure != NULL, 0);
769   g_return_val_if_fail (fieldname != NULL, 0);
770
771   field = gst_structure_get_field (structure, fieldname);
772
773   return (field != NULL);
774 }
775
776 /**
777  * gst_structure_has_field_typed:
778  * @structure: a #GstStructure
779  * @fieldname: the name of a field
780  * @type: the type of a value
781  *
782  * Accessor function.
783  *
784  * Returns: TRUE if the structure contains a field with the given name and type
785  */
786 gboolean
787 gst_structure_has_field_typed (const GstStructure * structure,
788     const gchar * fieldname, GType type)
789 {
790   GstStructureField *field;
791
792   g_return_val_if_fail (structure != NULL, 0);
793   g_return_val_if_fail (fieldname != NULL, 0);
794
795   field = gst_structure_get_field (structure, fieldname);
796   if (field == NULL)
797     return FALSE;
798
799   return (G_VALUE_TYPE (&field->value) == type);
800 }
801
802
803 /* utility functions */
804
805 /**
806  * gst_structure_get_boolean:
807  * @structure: a #GstStructure
808  * @fieldname: the name of a field
809  * @value: a pointer to a #gboolean to set
810  *
811  * Sets the boolean pointed to by @value corresponding to the value of the
812  * given field.  Caller is responsible for making sure the field exists
813  * and has the correct type.
814  *
815  * Returns: TRUE if the value could be set correctly
816  */
817 gboolean
818 gst_structure_get_boolean (const GstStructure * structure,
819     const gchar * fieldname, gboolean * value)
820 {
821   GstStructureField *field;
822
823   g_return_val_if_fail (structure != NULL, FALSE);
824   g_return_val_if_fail (fieldname != NULL, FALSE);
825
826   field = gst_structure_get_field (structure, fieldname);
827
828   if (field == NULL)
829     return FALSE;
830   if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
831     return FALSE;
832
833   *value = g_value_get_boolean (&field->value);
834
835   return TRUE;
836 }
837
838 /**
839  * gst_structure_get_int:
840  * @structure: a #GstStructure
841  * @fieldname: the name of a field
842  * @value: a pointer to an int to set
843  *
844  * Sets the int pointed to by @value corresponding to the value of the
845  * given field.  Caller is responsible for making sure the field exists
846  * and has the correct type.
847  *
848  * Returns: TRUE if the value could be set correctly
849  */
850 gboolean
851 gst_structure_get_int (const GstStructure * structure,
852     const gchar * fieldname, gint * value)
853 {
854   GstStructureField *field;
855
856   g_return_val_if_fail (structure != NULL, FALSE);
857   g_return_val_if_fail (fieldname != NULL, FALSE);
858   g_return_val_if_fail (value != NULL, FALSE);
859
860   field = gst_structure_get_field (structure, fieldname);
861
862   if (field == NULL)
863     return FALSE;
864   if (!G_VALUE_HOLDS_INT (&field->value))
865     return FALSE;
866
867   *value = g_value_get_int (&field->value);
868
869   return TRUE;
870 }
871
872 /**
873  * gst_structure_get_fourcc:
874  * @structure: a #GstStructure
875  * @fieldname: the name of a field
876  * @value: a pointer to a #GstFourcc to set
877  *
878  * Sets the #GstFourcc pointed to by @value corresponding to the value of the
879  * given field.  Caller is responsible for making sure the field exists
880  * and has the correct type.
881  *
882  * Returns: TRUE if the value could be set correctly
883  */
884 gboolean
885 gst_structure_get_fourcc (const GstStructure * structure,
886     const gchar * fieldname, guint32 * value)
887 {
888   GstStructureField *field;
889
890   g_return_val_if_fail (structure != NULL, FALSE);
891   g_return_val_if_fail (fieldname != NULL, FALSE);
892   g_return_val_if_fail (value != NULL, FALSE);
893
894   field = gst_structure_get_field (structure, fieldname);
895
896   if (field == NULL)
897     return FALSE;
898   if (!GST_VALUE_HOLDS_FOURCC (&field->value))
899     return FALSE;
900
901   *value = gst_value_get_fourcc (&field->value);
902
903   return TRUE;
904 }
905
906 /**
907  * gst_structure_get_double:
908  * @structure: a #GstStructure
909  * @fieldname: the name of a field
910  * @value: a pointer to a #GstFourcc to set
911  *
912  * Sets the double pointed to by @value corresponding to the value of the
913  * given field.  Caller is responsible for making sure the field exists
914  * and has the correct type.
915  *
916  * Returns: TRUE if the value could be set correctly
917  */
918 gboolean
919 gst_structure_get_double (const GstStructure * structure,
920     const gchar * fieldname, gdouble * value)
921 {
922   GstStructureField *field;
923
924   g_return_val_if_fail (structure != NULL, FALSE);
925   g_return_val_if_fail (fieldname != NULL, FALSE);
926   g_return_val_if_fail (value != NULL, FALSE);
927
928   field = gst_structure_get_field (structure, fieldname);
929
930   if (field == NULL)
931     return FALSE;
932   if (!G_VALUE_HOLDS_DOUBLE (&field->value))
933     return FALSE;
934
935   *value = g_value_get_double (&field->value);
936
937   return TRUE;
938 }
939
940 /**
941  * gst_structure_get_string:
942  * @structure: a #GstStructure
943  * @fieldname: the name of a field
944  *
945  * Finds the field corresponding to @fieldname, and returns the string
946  * contained in the field's value.  Caller is responsible for making
947  * sure the field exists and has the correct type.
948  *
949  * The string should not be modified, and remains valid until the next
950  * call to a gst_structure_*() function with the given structure.
951  *
952  * Returns: a pointer to the string
953  */
954 const gchar *
955 gst_structure_get_string (const GstStructure * structure,
956     const gchar * fieldname)
957 {
958   GstStructureField *field;
959
960   g_return_val_if_fail (structure != NULL, NULL);
961   g_return_val_if_fail (fieldname != NULL, NULL);
962
963   field = gst_structure_get_field (structure, fieldname);
964
965   if (field == NULL)
966     return FALSE;
967   if (!G_VALUE_HOLDS_STRING (&field->value))
968     return FALSE;
969
970   return g_value_get_string (&field->value);
971 }
972
973 typedef struct _GstStructureAbbreviation
974 {
975   char *type_name;
976   GType type;
977 }
978 GstStructureAbbreviation;
979
980 static GstStructureAbbreviation gst_structure_abbrs[] = {
981   {"int", G_TYPE_INT},
982   {"i", G_TYPE_INT},
983   {"float", G_TYPE_FLOAT},
984   {"f", G_TYPE_FLOAT},
985   {"double", G_TYPE_DOUBLE},
986   {"d", G_TYPE_DOUBLE},
987 //{ "fourcc",   GST_TYPE_FOURCC },
988   {"boolean", G_TYPE_BOOLEAN},
989   {"bool", G_TYPE_BOOLEAN},
990   {"b", G_TYPE_BOOLEAN},
991   {"string", G_TYPE_STRING},
992   {"str", G_TYPE_STRING},
993   {"s", G_TYPE_STRING}
994 };
995
996 static GType
997 gst_structure_from_abbr (const char *type_name)
998 {
999   int i;
1000
1001   g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1002
1003   for (i = 0; i < G_N_ELEMENTS (gst_structure_abbrs); i++) {
1004     if (strcmp (type_name, gst_structure_abbrs[i].type_name) == 0) {
1005       return gst_structure_abbrs[i].type;
1006     }
1007   }
1008
1009   /* FIXME shouldn't be a special case */
1010   if (strcmp (type_name, "fourcc") == 0 || strcmp (type_name, "4") == 0) {
1011     return GST_TYPE_FOURCC;
1012   }
1013   if (strcmp (type_name, "buffer") == 0) {
1014     return GST_TYPE_BUFFER;
1015   }
1016
1017   return g_type_from_name (type_name);
1018 }
1019
1020 static const char *
1021 gst_structure_to_abbr (GType type)
1022 {
1023   int i;
1024
1025   g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1026
1027   for (i = 0; i < G_N_ELEMENTS (gst_structure_abbrs); i++) {
1028     if (type == gst_structure_abbrs[i].type) {
1029       return gst_structure_abbrs[i].type_name;
1030     }
1031   }
1032
1033   /* FIXME shouldn't be a special case */
1034   if (type == GST_TYPE_FOURCC) {
1035     return "fourcc";
1036   }
1037   if (type == GST_TYPE_BUFFER) {
1038     return "buffer";
1039   }
1040
1041   return g_type_name (type);
1042 }
1043
1044 static GType
1045 gst_structure_value_get_generic_type (GValue * val)
1046 {
1047   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1048       || G_VALUE_TYPE (val) == GST_TYPE_FIXED_LIST) {
1049     GArray *array = g_value_peek_pointer (val);
1050
1051     if (array->len > 0) {
1052       GValue *value = &g_array_index (array, GValue, 0);
1053
1054       return gst_structure_value_get_generic_type (value);
1055     } else {
1056       return G_TYPE_INT;
1057     }
1058   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1059     return G_TYPE_INT;
1060   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1061     return G_TYPE_DOUBLE;
1062   }
1063   return G_VALUE_TYPE (val);
1064 }
1065
1066 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1067       ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1068       ((c) == '.'))
1069
1070 /**
1071  * gst_structure_to_string:
1072  * @structure: a #GstStructure
1073  *
1074  * Converts @structure to a human-readable representation.
1075  * 
1076  * Returns: a pointer to string allocated by g_malloc()
1077  */
1078 gchar *
1079 gst_structure_to_string (const GstStructure * structure)
1080 {
1081   GstStructureField *field;
1082   GString *s;
1083   int i;
1084
1085   /* NOTE:  This function is potentially called by the debug system,
1086    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1087    * should be careful to avoid recursion.  This includes any functions
1088    * called by gst_structure_to_string.  In particular, calls should
1089    * not use the GST_PTR_FORMAT extension.  */
1090
1091   g_return_val_if_fail (structure != NULL, NULL);
1092
1093   s = g_string_new ("");
1094   /* FIXME this string may need to be escaped */
1095   g_string_append_printf (s, "%s", g_quark_to_string (structure->name));
1096   for (i = 0; i < structure->fields->len; i++) {
1097     char *t;
1098     GType type;
1099
1100     field = GST_STRUCTURE_FIELD (structure, i);
1101
1102     t = gst_value_serialize (&field->value);
1103     type = gst_structure_value_get_generic_type (&field->value);
1104
1105     g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name),
1106         gst_structure_to_abbr (type), t);
1107     g_free (t);
1108   }
1109   return g_string_free (s, FALSE);
1110 }
1111
1112 /*
1113  * r will still point to the string. if end == next, the string will not be 
1114  * null-terminated. In all other cases it will be.
1115  * end = pointer to char behind end of string, next = pointer to start of
1116  * unread data.
1117  * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING 
1118  */
1119 static gboolean
1120 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1121 {
1122   gchar *w;
1123
1124   if (*s == 0)
1125     return FALSE;
1126
1127   if (*s != '"') {
1128     int ret;
1129
1130     ret = gst_structure_parse_simple_string (s, end);
1131     *next = *end;
1132
1133     return ret;
1134   }
1135
1136   w = s;
1137   s++;
1138   while (*s != '"') {
1139     if (*s == 0)
1140       return FALSE;
1141
1142     if (*s == '\\') {
1143       s++;
1144     }
1145
1146     *w = *s;
1147     w++;
1148     s++;
1149   }
1150   s++;
1151
1152   *end = w;
1153   *next = s;
1154
1155   return TRUE;
1156 }
1157
1158 static gboolean
1159 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1160     GType type)
1161 {
1162   GValue value1 = { 0 };
1163   GValue value2 = { 0 };
1164   GType range_type;
1165   gboolean ret;
1166
1167
1168   if (*s != '[')
1169     return FALSE;
1170   s++;
1171
1172   ret = gst_structure_parse_value (s, &s, &value1, type);
1173   if (ret == FALSE)
1174     return FALSE;
1175
1176   while (g_ascii_isspace (*s))
1177     s++;
1178
1179   if (*s != ',')
1180     return FALSE;
1181   s++;
1182
1183   while (g_ascii_isspace (*s))
1184     s++;
1185
1186   ret = gst_structure_parse_value (s, &s, &value2, type);
1187   if (ret == FALSE)
1188     return FALSE;
1189
1190   while (g_ascii_isspace (*s))
1191     s++;
1192
1193   if (*s != ']')
1194     return FALSE;
1195   s++;
1196
1197   if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1198     return FALSE;
1199
1200   if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1201     range_type = GST_TYPE_DOUBLE_RANGE;
1202   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1203     range_type = GST_TYPE_INT_RANGE;
1204   } else {
1205     return FALSE;
1206   }
1207
1208   g_value_init (value, range_type);
1209   if (range_type == GST_TYPE_DOUBLE_RANGE) {
1210     gst_value_set_double_range (value, g_value_get_double (&value1),
1211         g_value_get_double (&value2));
1212   } else {
1213     gst_value_set_int_range (value, g_value_get_int (&value1),
1214         g_value_get_int (&value2));
1215   }
1216
1217   *after = s;
1218   return TRUE;
1219 }
1220
1221 static gboolean
1222 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1223     GType type, GType list_type, char begin, char end)
1224 {
1225   GValue list_value = { 0 };
1226   gboolean ret;
1227   GArray *array;
1228
1229   g_value_init (value, list_type);
1230   array = g_value_peek_pointer (value);
1231
1232   if (*s != begin)
1233     return FALSE;
1234   s++;
1235
1236   while (g_ascii_isspace (*s))
1237     s++;
1238   if (*s == end) {
1239     s++;
1240     *after = s;
1241     return TRUE;
1242   }
1243
1244   ret = gst_structure_parse_value (s, &s, &list_value, type);
1245   if (ret == FALSE)
1246     return FALSE;
1247
1248   g_array_append_val (array, list_value);
1249
1250   while (g_ascii_isspace (*s))
1251     s++;
1252
1253   while (*s != end) {
1254     if (*s != ',')
1255       return FALSE;
1256     s++;
1257
1258     while (g_ascii_isspace (*s))
1259       s++;
1260
1261     memset (&list_value, 0, sizeof (list_value));
1262     ret = gst_structure_parse_value (s, &s, &list_value, type);
1263     if (ret == FALSE)
1264       return FALSE;
1265
1266     g_array_append_val (array, list_value);
1267     while (g_ascii_isspace (*s))
1268       s++;
1269   }
1270
1271   s++;
1272
1273   *after = s;
1274   return TRUE;
1275 }
1276
1277 static gboolean
1278 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1279 {
1280   return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1281       '{', '}');
1282 }
1283
1284 static gboolean
1285 gst_structure_parse_fixed_list (gchar * s, gchar ** after, GValue * value,
1286     GType type)
1287 {
1288   return gst_structure_parse_any_list (s, after, value, type,
1289       GST_TYPE_FIXED_LIST, '<', '>');
1290 }
1291
1292 static gboolean
1293 gst_structure_parse_simple_string (gchar * str, gchar ** end)
1294 {
1295   char *s = str;
1296
1297   while (GST_ASCII_IS_STRING (*s)) {
1298     s++;
1299   }
1300
1301   *end = s;
1302
1303   return (s != str);
1304 }
1305
1306 static gboolean
1307 gst_structure_parse_field (gchar * str,
1308     gchar ** after, GstStructureField * field)
1309 {
1310   gchar *name;
1311   gchar *name_end;
1312   gchar *s;
1313   gchar c;
1314
1315   s = str;
1316
1317   while (g_ascii_isspace (*s))
1318     s++;
1319   name = s;
1320   if (!gst_structure_parse_simple_string (s, &name_end))
1321     return FALSE;
1322
1323   s = name_end;
1324   while (g_ascii_isspace (*s))
1325     s++;
1326
1327   if (*s != '=')
1328     return FALSE;
1329   s++;
1330
1331   c = *name_end;
1332   *name_end = 0;
1333   field->name = g_quark_from_string (name);
1334   *name_end = c;
1335
1336   if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1337     return FALSE;
1338
1339   *after = s;
1340   return TRUE;
1341 }
1342
1343 static gboolean
1344 gst_structure_parse_value (gchar * str,
1345     gchar ** after, GValue * value, GType default_type)
1346 {
1347   gchar *type_name;
1348   gchar *type_end;
1349   gchar *value_s;
1350   gchar *value_end;
1351   gchar *s;
1352   gchar c;
1353   int ret = 0;
1354   GType type = default_type;
1355
1356
1357   s = str;
1358   while (g_ascii_isspace (*s))
1359     s++;
1360
1361   type_name = NULL;
1362   if (*s == '(') {
1363     type = G_TYPE_INVALID;
1364
1365     s++;
1366     while (g_ascii_isspace (*s))
1367       s++;
1368     type_name = s;
1369     if (!gst_structure_parse_simple_string (s, &type_end))
1370       return FALSE;
1371     s = type_end;
1372     while (g_ascii_isspace (*s))
1373       s++;
1374     if (*s != ')')
1375       return FALSE;
1376     s++;
1377     while (g_ascii_isspace (*s))
1378       s++;
1379
1380     c = *type_end;
1381     *type_end = 0;
1382     type = gst_structure_from_abbr (type_name);
1383     *type_end = c;
1384
1385     if (type == G_TYPE_INVALID)
1386       return FALSE;
1387   }
1388
1389   while (g_ascii_isspace (*s))
1390     s++;
1391   if (*s == '[') {
1392     ret = gst_structure_parse_range (s, &s, value, type);
1393   } else if (*s == '{') {
1394     ret = gst_structure_parse_list (s, &s, value, type);
1395   } else if (*s == '<') {
1396     ret = gst_structure_parse_fixed_list (s, &s, value, type);
1397   } else {
1398     value_s = s;
1399     if (!gst_structure_parse_string (s, &value_end, &s))
1400       return FALSE;
1401
1402     c = *value_end;
1403     *value_end = 0;
1404     if (type == G_TYPE_INVALID) {
1405       GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1406       int i;
1407
1408       for (i = 0; i < 3; i++) {
1409         g_value_init (value, try_types[i]);
1410         ret = gst_value_deserialize (value, value_s);
1411         if (ret)
1412           break;
1413         g_value_unset (value);
1414       }
1415     } else {
1416       g_value_init (value, type);
1417
1418       ret = gst_value_deserialize (value, value_s);
1419     }
1420     *value_end = c;
1421   }
1422
1423   *after = s;
1424
1425   return ret;
1426 }
1427
1428 /**
1429  * gst_structure_from_string:
1430  * @string: a string representation of a #GstStructure.
1431  * @end: FIXME, deduce from code
1432  *
1433  * Creates a #GstStructure from a string representation.
1434  * 
1435  * Returns: a new #GstStructure
1436  */
1437 GstStructure *
1438 gst_structure_from_string (const gchar * string, gchar ** end)
1439 {
1440   char *name;
1441   char *copy;
1442   char *w;
1443   char *r;
1444   char save;
1445   GstStructure *structure = NULL;
1446   GstStructureField field = { 0 };
1447
1448   g_return_val_if_fail (string != NULL, NULL);
1449
1450   copy = g_strdup (string);
1451   r = copy;
1452
1453   name = r;
1454   if (!gst_structure_parse_string (r, &w, &r))
1455     goto error;
1456
1457   while (g_ascii_isspace (*r))
1458     r++;
1459   if (*r != 0 && *r != ';' && *r != ',')
1460     goto error;
1461
1462   save = *w;
1463   *w = 0;
1464   structure = gst_structure_empty_new (name);
1465   *w = save;
1466
1467   while (*r && (*r != ';')) {
1468     if (*r != ',')
1469       goto error;
1470     r++;
1471     while (*r && g_ascii_isspace (*r))
1472       r++;
1473
1474     memset (&field, 0, sizeof (field));
1475     if (!gst_structure_parse_field (r, &r, &field))
1476       goto error;
1477     gst_structure_set_field (structure, &field);
1478     while (*r && g_ascii_isspace (*r))
1479       r++;
1480   }
1481
1482   if (end)
1483     *end = (char *) string + (r - copy);
1484
1485   g_free (copy);
1486   return structure;
1487
1488 error:
1489   if (structure)
1490     gst_structure_free (structure);
1491   g_free (copy);
1492   return NULL;
1493 }
1494
1495 static void
1496 gst_structure_transform_to_string (const GValue * src_value,
1497     GValue * dest_value)
1498 {
1499   g_return_if_fail (src_value != NULL);
1500   g_return_if_fail (dest_value != NULL);
1501
1502   dest_value->data[0].v_pointer =
1503       gst_structure_to_string (src_value->data[0].v_pointer);
1504 }
1505
1506 static GstStructure *
1507 gst_structure_copy_conditional (const GstStructure * structure)
1508 {
1509   if (structure)
1510     return gst_structure_copy (structure);
1511   return NULL;
1512 }