2 * Copyright (C) 2003 David A. Schleef <ds@schleef.org>
4 * gststructure.c: lists of { GQuark, GValue } tuples
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.
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.
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.
29 #include <gobject/gvaluecollector.h>
31 static GType _gst_structure_type;
33 typedef struct _GstStructureField GstStructureField;
34 struct _GstStructureField {
39 #define GST_STRUCTURE_FIELD(structure, index) \
40 &g_array_index((structure)->fields, GstStructureField, (index))
42 static void gst_structure_set_field (GstStructure *structure,
43 GstStructureField *field);
44 static GstStructureField *gst_structure_get_field(const GstStructure *structure,
45 const gchar *fieldname);
46 static GstStructureField *gst_structure_id_get_field(const GstStructure *structure,
49 static void _gst_structure_transform_to_string(const GValue *src_value,
52 static void _gst_structure_value_init (GValue *value);
53 static void _gst_structure_value_free (GValue *value);
54 static void _gst_structure_value_copy (const GValue *src, GValue *dest);
55 static gpointer _gst_structure_value_peek_pointer (const GValue *value);
58 GType gst_structure_get_type(void)
60 return _gst_structure_type;
63 void _gst_structure_initialize(void)
65 static const GTypeValueTable type_value_table = {
66 _gst_structure_value_init,
67 _gst_structure_value_free,
68 _gst_structure_value_copy,
69 _gst_structure_value_peek_pointer,
75 static const GTypeInfo structure_info = {
82 0, /* sizeof(GstStructure), */
84 NULL, /* _gst_structure_init, */
88 _gst_structure_type = g_type_register_static(G_TYPE_BOXED, "GstStructure",
91 _gst_structure_type = g_boxed_type_register_static("GstStructure",
92 (GBoxedCopyFunc) gst_structure_copy,
93 (GBoxedFreeFunc) gst_structure_free);
96 g_value_register_transform_func(_gst_structure_type, G_TYPE_STRING,
97 _gst_structure_transform_to_string);
101 * gst_structure_id_empty_new:
102 * @name: name of new structure
104 * Creates a new, empty #GstStructure with the given name.
106 * Returns: a new, empty #GstStructure
108 GstStructure *gst_structure_id_empty_new(GQuark quark)
110 GstStructure *structure;
112 g_return_val_if_fail(quark != 0, NULL);
114 structure = g_new0(GstStructure, 1);
115 structure->name = quark;
116 structure->fields = g_array_new(FALSE,TRUE,sizeof(GstStructureField));
122 * gst_structure_empty_new:
123 * @name: name of new structure
125 * Creates a new, empty #GstStructure with the given name.
127 * Returns: a new, empty #GstStructure
129 GstStructure *gst_structure_empty_new(const gchar *name)
131 GstStructure *structure;
133 g_return_val_if_fail(name != NULL, NULL);
135 structure = g_new0(GstStructure, 1);
136 structure->name = g_quark_from_string(name);
137 structure->fields = g_array_new(FALSE,TRUE,sizeof(GstStructureField));
144 * @name: name of new structure
145 * @firstfield: name of first field to set
146 * @...: additional arguments
148 * Creates a new #GstStructure with the given name. Parses the
149 * list of variable arguments and sets fields to the values listed.
150 * Variable arguments should be passed as field name, field type,
151 * and value. Last variable argument should be NULL.
153 * Returns: a new #GstStructure
155 GstStructure *gst_structure_new(const gchar *name,
156 const gchar *firstfield, ...)
158 GstStructure *structure;
161 g_return_val_if_fail(name != NULL, NULL);
163 va_start(varargs, firstfield);
165 structure = gst_structure_new_valist(name,firstfield,varargs);
173 * gst_structure_new_valist:
174 * @name: name of new structure
175 * @firstfield: name of first field to set
176 * @varags: variable argument list
178 * Creates a new #GstStructure with the given name. Structure fields
179 * are set according to the varargs in a manner similar to
180 * @gst_structure_new.
182 * Returns: a new #GstStructure
184 GstStructure *gst_structure_new_valist(const gchar *name,
185 const gchar *firstfield, va_list varargs)
187 GstStructure *structure;
189 g_return_val_if_fail(name != NULL, NULL);
191 structure = gst_structure_empty_new(name);
192 gst_structure_set_valist(structure, firstfield, varargs);
198 * gst_structure_copy:
199 * @structure: a #GstStructure to duplicate
201 * Duplicates a #GstStructure and all its fields and values.
203 * Returns: a new #GstStructure.
205 GstStructure *gst_structure_copy(GstStructure *structure)
207 GstStructure *new_structure;
208 GstStructureField *field;
211 g_return_val_if_fail(structure != NULL, NULL);
213 new_structure = gst_structure_empty_new(g_quark_to_string(structure->name));
214 new_structure->name = structure->name;
216 for(i=0;i<structure->fields->len;i++){
217 GstStructureField new_field = { 0 };
219 field = GST_STRUCTURE_FIELD(structure, i);
221 new_field.name = field->name;
222 gst_value_init_and_copy (&new_field.value, &field->value);
223 g_array_append_val(new_structure->fields, new_field);
226 return new_structure;
230 * gst_structure_free:
231 * @structure: the #GstStructure to free
233 * Frees a #GstStructure and all its fields and values.
235 void gst_structure_free(GstStructure *structure)
237 GstStructureField *field;
242 g_return_if_fail(structure != NULL);
244 for(i=0;i<structure->fields->len;i++){
245 field = GST_STRUCTURE_FIELD(structure, i);
247 if(G_IS_VALUE(&field->value)){
248 g_value_unset(&field->value);
252 memset (structure, 0xff, sizeof(GstStructure));
258 * gst_structure_get_name:
259 * @structure: a #GstStructure
263 * Returns: the name of the structure.
265 const gchar *gst_structure_get_name(const GstStructure *structure)
267 g_return_val_if_fail(structure != NULL, NULL);
269 return g_quark_to_string(structure->name);
273 * gst_structure_set_name:
274 * @structure: a #GstStructure
275 * @name: the new name of the structure
277 * Sets the name of the structure to the given name. The string
278 * provided is copied before being used.
280 void gst_structure_set_name(GstStructure *structure, const gchar *name)
282 g_return_if_fail(structure != NULL);
283 g_return_if_fail(name != NULL);
285 structure->name = g_quark_from_string(name);
289 * gst_structure_id_set_value:
290 * @structure: a #GstStructure
291 * @field_id: a #GQuark representing a field
292 * @value: the new value of the field
294 * Sets the field with the given ID to the provided value. If the field
295 * does not exist, it is created. If the field exists, the previous
298 void gst_structure_id_set_value(GstStructure *structure, GQuark fieldname,
301 GstStructureField field = { 0, { 0, } };
303 g_return_if_fail(structure != NULL);
304 g_return_if_fail(G_IS_VALUE(value));
306 field.name = fieldname;
307 gst_value_init_and_copy (&field.value, value);
309 gst_structure_set_field(structure, &field);
313 * gst_structure_set_value:
314 * @structure: a #GstStructure
315 * @field: the name of the field to set
316 * @value: the new value of the field
318 * Sets the field with the given name to the provided value. If the field
319 * does not exist, it is created. If the field exists, the previous
322 void gst_structure_set_value(GstStructure *structure, const gchar *field,
325 g_return_if_fail(structure != NULL);
326 g_return_if_fail(field != NULL);
327 g_return_if_fail(G_IS_VALUE(value));
329 gst_structure_id_set_value(structure, g_quark_from_string(field), value);
334 * @structure: a #GstStructure
335 * @field: the name of the field to set
336 * @...: variable arguments
338 * Parses the variable arguments and sets fields accordingly.
339 * Variable arguments should be in the form field name, field type
340 * (as a GType), value. The last variable argument should be NULL.
342 void gst_structure_set(GstStructure *structure, const gchar *field, ...)
346 g_return_if_fail(structure != NULL);
348 va_start(varargs, field);
350 gst_structure_set_valist(structure,field,varargs);
356 * gst_structure_set_valist:
357 * @structure: a #GstStructure
358 * @field: the name of the field to set
359 * @varargs: variable arguments
361 * va_list form of #gst_structure_set.
363 void gst_structure_set_valist(GstStructure *structure, const gchar *fieldname,
371 g_return_if_fail(structure != NULL);
374 GstStructureField field = { 0 };
376 field.name = g_quark_from_string(fieldname);
378 type = va_arg (varargs, GType);
382 i = va_arg(varargs, int);
383 g_value_init(&field.value, G_TYPE_INT);
384 g_value_set_int(&field.value, i);
387 d = va_arg(varargs, double);
388 g_value_init(&field.value, G_TYPE_DOUBLE);
389 g_value_set_double(&field.value, d);
392 i = va_arg(varargs, int);
393 g_value_init(&field.value, G_TYPE_BOOLEAN);
394 g_value_set_boolean(&field.value, i);
397 s = va_arg(varargs, char *);
398 g_value_init(&field.value, G_TYPE_STRING);
399 g_value_set_string(&field.value, s);
402 if(type == GST_TYPE_FOURCC){
403 i = va_arg(varargs, int);
404 g_value_init(&field.value, GST_TYPE_FOURCC);
405 gst_value_set_fourcc(&field.value, i);
406 } else if (type == GST_TYPE_INT_RANGE){
408 min = va_arg(varargs, int);
409 max = va_arg(varargs, int);
410 g_value_init(&field.value, GST_TYPE_INT_RANGE);
411 gst_value_set_int_range(&field.value, min, max);
412 } else if (type == GST_TYPE_DOUBLE_RANGE){
414 min = va_arg(varargs, double);
415 max = va_arg(varargs, double);
416 g_value_init(&field.value, GST_TYPE_DOUBLE_RANGE);
417 gst_value_set_double_range(&field.value, min, max);
419 g_critical("unimplemented vararg field type %d\n", (int)type);
425 gst_structure_set_field(structure, &field);
427 fieldname = va_arg (varargs, gchar *);
432 * gst_structure_set_field:
433 * @structure: a #GstStructure
434 * @field: the #GstStructureField to set
436 * Sets a field in the structure. If the structure currently contains
437 * a field with the same name, it is replaced with the provided field.
438 * Otherwise, the field is added to the structure. The field's value
439 * is not deeply copied.
441 * This function is intended mainly for internal use. The function
442 * #gst_structure_set() is recommended instead of this one.
444 static void gst_structure_set_field(GstStructure *structure, GstStructureField *field)
446 GstStructureField *f;
449 for(i=0;i<structure->fields->len;i++){
450 f = GST_STRUCTURE_FIELD(structure, i);
452 if(f->name == field->name){
453 g_value_unset(&f->value);
454 memcpy(f,field,sizeof(GstStructureField));
459 g_array_append_val(structure->fields, *field);
463 * gst_structure_id_get_field:
464 * @structure: a #GstStructure
465 * @field_id: the GQuark of the field to get
467 * Gets the specified field from the structure. If there is no
468 * field with the given ID, NULL is returned.
470 * Returns: the #GstStructureField with the given ID
472 static GstStructureField *gst_structure_id_get_field(const GstStructure *structure,
475 GstStructureField *field;
478 g_return_val_if_fail(structure != NULL, NULL);
480 for(i=0;i<structure->fields->len;i++){
481 field = GST_STRUCTURE_FIELD(structure, i);
483 if(field->name == field_id) return field;
490 * gst_structure_get_field:
491 * @structure: a #GstStructure
492 * @fieldname: the name of the field to get
494 * Gets the specified field from the structure. If there is no
495 * field with the given ID, NULL is returned.
497 * Returns: the #GstStructureField with the given name
499 static GstStructureField *
500 gst_structure_get_field(const GstStructure *structure, const gchar *fieldname)
502 g_return_val_if_fail(structure != NULL, NULL);
503 g_return_val_if_fail(fieldname != NULL, NULL);
505 return gst_structure_id_get_field(structure,
506 g_quark_from_string(fieldname));
510 * gst_structure_get_value:
511 * @structure: a #GstStructure
512 * @fieldname: the name of the field to get
516 * Returns: the #GValue corresponding to the field with the given name.
519 gst_structure_get_value(const GstStructure *structure, const gchar *fieldname)
521 GstStructureField *field;
523 g_return_val_if_fail(structure != NULL, NULL);
524 g_return_val_if_fail(fieldname != NULL, NULL);
526 field = gst_structure_get_field(structure, fieldname);
527 if(field == NULL) return NULL;
529 return &field->value;
533 * gst_structure_id_get_value:
534 * @structure: a #GstStructure
535 * @id: the #GQuark of the field to get
539 * Returns: the #GValue corresponding to the field with the given name
543 gst_structure_id_get_value(const GstStructure *structure, GQuark id)
545 GstStructureField *field;
547 g_return_val_if_fail(structure != NULL, NULL);
549 field = gst_structure_id_get_field(structure, id);
550 if(field == NULL) return NULL;
552 return &field->value;
556 void gst_structure_get(GstStructure *structure, const gchar *fieldname, ...)
563 * gst_structure_remove_field:
564 * @structure: a #GstStructure
565 * @fieldname: the name of the field to remove
567 * Removes the field with the given name. If the field with the given
568 * name does not exist, the structure is unchanged.
571 gst_structure_remove_field(GstStructure *structure, const gchar *fieldname)
573 GstStructureField *field;
577 g_return_if_fail(structure != NULL);
578 g_return_if_fail(fieldname != NULL);
580 id = g_quark_from_string(fieldname);
582 for(i=0;i<structure->fields->len;i++){
583 field = GST_STRUCTURE_FIELD(structure, i);
585 if(field->name == id){
586 if(G_IS_VALUE(&field->value)){
587 g_value_unset(&field->value);
589 structure->fields = g_array_remove_index(structure->fields, i);
596 * gst_structure_remove_all_fields:
597 * @structure: a #GstStructure
599 * Removes all fields in a GstStructure.
602 gst_structure_remove_all_fields(GstStructure *structure)
604 GstStructureField *field;
607 g_return_if_fail(structure != NULL);
609 for (i = structure->fields->len - 1; i >= 0; i-- ) {
610 field = GST_STRUCTURE_FIELD(structure, i);
612 if (G_IS_VALUE (&field->value)) {
613 g_value_unset(&field->value);
615 structure->fields = g_array_remove_index (structure->fields, i);
620 * gst_structure_get_field_type:
621 * @structure: a #GstStructure
622 * @fieldname: the name of the field
624 * Finds the field with the given name, and returns the type of the
625 * value it contains. If the field is not found, G_TYPE_INVALID is
628 * Returns: the #GValue of the field
631 gst_structure_get_field_type(const GstStructure *structure, const gchar *fieldname)
633 GstStructureField *field;
635 g_return_val_if_fail(structure != NULL, G_TYPE_INVALID);
636 g_return_val_if_fail(fieldname != NULL, G_TYPE_INVALID);
638 field = gst_structure_get_field(structure, fieldname);
639 if(field == NULL) return G_TYPE_INVALID;
641 return G_VALUE_TYPE(&field->value);
645 * gst_structure_n_fields:
646 * @structure: a #GstStructure
650 * Returns: the number of fields in the structure
653 gst_structure_n_fields(const GstStructure *structure)
655 g_return_val_if_fail(structure != NULL, 0);
657 return structure->fields->len;
661 * gst_structure_foreach:
662 * @structure: a #GstStructure
663 * @func: a function to call for each field
664 * @user_data: private data
666 * Calls the provided function once for each field in the #GstStructure.
669 gst_structure_foreach (GstStructure *structure,
670 GstStructureForeachFunc func, gpointer user_data)
673 GstStructureField *field;
676 for(i=0;i<structure->fields->len;i++){
677 field = GST_STRUCTURE_FIELD(structure, i);
679 ret = func (field->name, &field->value, user_data);
680 if (!ret) return FALSE;
687 * gst_structure_has_field:
688 * @structure: a #GstStructure
689 * @fieldname: the name of a field
693 * Returns: TRUE if the structure contains a field with the given name
696 gst_structure_has_field(const GstStructure *structure, const gchar *fieldname)
698 GstStructureField *field;
700 g_return_val_if_fail(structure != NULL, 0);
701 g_return_val_if_fail(fieldname != NULL, 0);
703 field = gst_structure_get_field(structure, fieldname);
705 return (field != NULL);
709 * gst_structure_has_field:
710 * @structure: a #GstStructure
711 * @fieldname: the name of a field
712 * @type: the type of a value
716 * Returns: TRUE if the structure contains a field with the given name and type
719 gst_structure_has_field_typed(const GstStructure *structure, const gchar *fieldname,
722 GstStructureField *field;
724 g_return_val_if_fail(structure != NULL, 0);
725 g_return_val_if_fail(fieldname != NULL, 0);
727 field = gst_structure_get_field(structure, fieldname);
728 if(field == NULL) return FALSE;
730 return (G_VALUE_TYPE(&field->value) == type);
734 /* utility functions */
737 * gst_structure_get_boolean:
738 * @structure: a #GstStructure
739 * @fieldname: the name of a field
740 * @ptr: a pointer to a #gboolean to set
742 * Sets the boolean pointed to by @ptr corresponding to the value of the
743 * given field. Caller is responsible for making sure the field exists
744 * and has the correct type.
746 * Returns: TRUE if the value could be set correctly
749 gst_structure_get_boolean(const GstStructure *structure, const gchar *fieldname,
752 GstStructureField *field;
754 g_return_val_if_fail(structure != NULL, FALSE);
755 g_return_val_if_fail(fieldname != NULL, FALSE);
757 field = gst_structure_get_field(structure, fieldname);
759 if(field == NULL) return FALSE;
760 if(!G_VALUE_HOLDS_BOOLEAN(&field->value))return FALSE;
762 *value = g_value_get_boolean(&field->value);
768 * gst_structure_get_int:
769 * @structure: a #GstStructure
770 * @fieldname: the name of a field
771 * @ptr: a pointer to an int to set
773 * Sets the int pointed to by @ptr corresponding to the value of the
774 * given field. Caller is responsible for making sure the field exists
775 * and has the correct type.
777 * Returns: TRUE if the value could be set correctly
780 gst_structure_get_int(const GstStructure *structure, const gchar *fieldname,
783 GstStructureField *field;
785 g_return_val_if_fail(structure != NULL, FALSE);
786 g_return_val_if_fail(fieldname != NULL, FALSE);
787 g_return_val_if_fail(value != NULL, FALSE);
789 field = gst_structure_get_field(structure, fieldname);
791 if(field == NULL) return FALSE;
792 if(!G_VALUE_HOLDS_INT(&field->value))return FALSE;
794 *value = g_value_get_int(&field->value);
800 * gst_structure_get_fourcc:
801 * @structure: a #GstStructure
802 * @fieldname: the name of a field
803 * @ptr: a pointer to a #GstFourcc to set
805 * Sets the #GstFourcc pointed to by @ptr corresponding to the value of the
806 * given field. Caller is responsible for making sure the field exists
807 * and has the correct type.
809 * Returns: TRUE if the value could be set correctly
812 gst_structure_get_fourcc(const GstStructure *structure, const gchar *fieldname,
815 GstStructureField *field;
817 g_return_val_if_fail(structure != NULL, FALSE);
818 g_return_val_if_fail(fieldname != NULL, FALSE);
819 g_return_val_if_fail(value != NULL, FALSE);
821 field = gst_structure_get_field(structure, fieldname);
823 if(field == NULL) return FALSE;
824 if(!GST_VALUE_HOLDS_FOURCC(&field->value))return FALSE;
826 *value = gst_value_get_fourcc (&field->value);
832 * gst_structure_get_double:
833 * @structure: a #GstStructure
834 * @fieldname: the name of a field
835 * @ptr: a pointer to a #GstFourcc to set
837 * Sets the double pointed to by @ptr corresponding to the value of the
838 * given field. Caller is responsible for making sure the field exists
839 * and has the correct type.
841 * Returns: TRUE if the value could be set correctly
843 gboolean gst_structure_get_double(const GstStructure *structure,
844 const gchar *fieldname, gdouble *value)
846 GstStructureField *field;
848 g_return_val_if_fail(structure != NULL, FALSE);
849 g_return_val_if_fail(fieldname != NULL, FALSE);
850 g_return_val_if_fail(value != NULL, FALSE);
852 field = gst_structure_get_field(structure, fieldname);
854 if(field == NULL) return FALSE;
855 if(!G_VALUE_HOLDS_DOUBLE(&field->value))return FALSE;
857 *value = g_value_get_double(&field->value);
863 * gst_structure_get_string:
864 * @structure: a #GstStructure
865 * @fieldname: the name of a field
866 * @ptr: a pointer to a #GstFourcc to set
868 * Finds the field corresponding to @fieldname, and returns the string
869 * contained in the field's value. Caller is responsible for making
870 * sure the field exists and has the correct type.
872 * The string should not be modified, and remains valid until the next
873 * call to a gst_structure_*() function with the given structure.
875 * Returns: a pointer to the string
878 gst_structure_get_string(const GstStructure *structure, const gchar *fieldname)
880 GstStructureField *field;
882 g_return_val_if_fail(structure != NULL, NULL);
883 g_return_val_if_fail(fieldname != NULL, NULL);
885 field = gst_structure_get_field(structure, fieldname);
887 if(field == NULL) return FALSE;
888 if(!G_VALUE_HOLDS_STRING(&field->value))return FALSE;
890 return g_value_get_string(&field->value);
893 typedef struct _GstStructureAbbreviation {
896 } GstStructureAbbreviation;
898 static GstStructureAbbreviation _gst_structure_abbrs[] = {
899 { "int", G_TYPE_INT },
901 { "float", G_TYPE_FLOAT },
902 { "f", G_TYPE_FLOAT },
903 { "double", G_TYPE_DOUBLE },
904 { "d", G_TYPE_DOUBLE },
905 //{ "fourcc", GST_TYPE_FOURCC },
906 { "boolean", G_TYPE_BOOLEAN },
907 { "bool", G_TYPE_BOOLEAN },
908 { "b", G_TYPE_BOOLEAN },
909 { "string", G_TYPE_STRING },
910 { "str", G_TYPE_STRING },
911 { "s", G_TYPE_STRING }
914 static GType _gst_structure_from_abbr(const char *type_name)
918 g_return_val_if_fail(type_name != NULL, G_TYPE_INVALID);
920 for(i=0;i<G_N_ELEMENTS(_gst_structure_abbrs);i++){
921 if(strcmp(type_name,_gst_structure_abbrs[i].type_name)==0){
922 return _gst_structure_abbrs[i].type;
926 /* FIXME shouldn't be a special case */
927 if (strcmp (type_name,"fourcc") == 0 || strcmp (type_name, "4") == 0) {
928 return GST_TYPE_FOURCC;
931 return g_type_from_name (type_name);
934 static const char *_gst_structure_to_abbr(GType type)
938 g_return_val_if_fail(type != G_TYPE_INVALID, NULL);
940 for(i=0;i<G_N_ELEMENTS(_gst_structure_abbrs);i++){
941 if(type == _gst_structure_abbrs[i].type){
942 return _gst_structure_abbrs[i].type_name;
946 /* FIXME shouldn't be a special case */
947 if (type == GST_TYPE_FOURCC) {
951 return g_type_name(type);
954 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
955 ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
959 * gst_structure_to_string:
960 * @structure: a #GstStructure
962 * Converts @structure to a human-readable representation.
964 * Returns: a pointer to string allocated by g_malloc()
967 gst_structure_to_string(const GstStructure *structure)
969 GstStructureField *field;
973 g_return_val_if_fail(structure != NULL, NULL);
975 s = g_string_new("");
976 /* FIXME this string may need to be escaped */
977 g_string_append_printf(s, "%s", g_quark_to_string(structure->name));
978 for(i=0;i<structure->fields->len;i++) {
982 field = GST_STRUCTURE_FIELD(structure, i);
984 t = gst_value_serialize (&field->value);
985 type = G_VALUE_TYPE (&field->value);
987 if (type == GST_TYPE_LIST) {
988 GArray *array = g_value_peek_pointer (&field->value);
990 GValue *value = &g_array_index (array, GValue, 0);
992 type = G_VALUE_TYPE (value);
996 } else if (G_VALUE_TYPE(&field->value) == GST_TYPE_INT_RANGE) {
998 } else if (G_VALUE_TYPE(&field->value) == GST_TYPE_DOUBLE_RANGE) {
999 type = G_TYPE_DOUBLE;
1001 g_string_append_printf(s, ", %s=(%s)%s", g_quark_to_string(field->name),
1002 _gst_structure_to_abbr(type), t);
1005 return g_string_free(s, FALSE);
1009 * r will still point to the string. if end == next, the string will not be
1010 * null-terminated. In all other cases it will be.
1011 * end = pointer to char behind end of string, next = pointer to start of
1013 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1015 static gboolean _gst_structure_parse_simple_string (gchar *s, gchar **end);
1017 _gst_structure_parse_string (gchar *s, gchar **end, gchar **next)
1021 if (*s == 0) return FALSE;
1026 ret = _gst_structure_parse_simple_string (s, end);
1035 if (*s == 0) return FALSE;
1054 gst_strtoi (const char *s, char **end, int base)
1059 i = - (int) strtoul (s + 1, end, base);
1061 i = strtoul (s, end, base);
1068 gst_value_from_string (GValue *value, const char *s)
1070 gboolean ret = FALSE;
1072 GType type = G_VALUE_TYPE (value);
1074 if (type == G_TYPE_INVALID) return FALSE;
1080 x = gst_strtoi (s, &end, 0);
1084 if (g_ascii_strcasecmp (s, "little_endian") == 0) {
1085 x = G_LITTLE_ENDIAN;
1087 } else if (g_ascii_strcasecmp (s, "big_endian") == 0) {
1090 } else if (g_ascii_strcasecmp (s, "byte_order") == 0) {
1093 } else if (g_ascii_strcasecmp (s, "min") == 0) {
1096 } else if (g_ascii_strcasecmp (s, "max") == 0) {
1102 g_value_set_int (value, x);
1109 x = g_ascii_strtod (s, &end);
1111 g_value_set_float (value, x);
1119 x = g_ascii_strtod (s, &end);
1123 if (g_ascii_strcasecmp (s, "min") == 0) {
1126 } else if (g_ascii_strcasecmp (s, "max") == 0) {
1132 g_value_set_double (value, x);
1136 case G_TYPE_BOOLEAN:
1138 if (g_ascii_strcasecmp (s, "true") == 0 ||
1139 g_ascii_strcasecmp (s, "yes") == 0 ||
1140 g_ascii_strcasecmp (s, "t") == 0 ||
1141 strcmp (s, "1") == 0) {
1142 g_value_set_boolean (value, TRUE);
1144 } else if (g_ascii_strcasecmp (s, "false") == 0 ||
1145 g_ascii_strcasecmp (s, "no") == 0 ||
1146 g_ascii_strcasecmp (s, "f") == 0 ||
1147 strcmp (s, "0") == 0) {
1148 g_value_set_boolean (value, FALSE);
1155 g_value_set_string (value, s);
1160 /* FIXME: make more general */
1161 if (type == GST_TYPE_FOURCC) {
1163 if (strlen(s) == 4) {
1164 fourcc = GST_MAKE_FOURCC(s[0], s[1], s[2], s[3]);
1166 } else if (g_ascii_isdigit (*s)) {
1167 fourcc = strtoul (s, &end, 0);
1172 gst_value_set_fourcc (value, fourcc);
1174 g_critical("type %s not handled", g_type_name(type));
1182 static gboolean _gst_structure_parse_value (gchar *str, gchar **after,
1183 GValue *value, GType default_type);
1186 _gst_structure_parse_range (gchar *s, gchar **after, GValue *value, GType type)
1188 GValue value1 = { 0 };
1189 GValue value2 = { 0 };
1194 if (*s != '[') return FALSE;
1197 ret = _gst_structure_parse_value(s, &s, &value1, type);
1198 if (ret == FALSE) return FALSE;
1200 while (g_ascii_isspace (*s)) s++;
1202 if (*s != ',') return FALSE;
1205 while (g_ascii_isspace (*s)) s++;
1207 ret = _gst_structure_parse_value(s, &s, &value2, type);
1208 if (ret == FALSE) return FALSE;
1210 while (g_ascii_isspace (*s)) s++;
1212 if (*s != ']') return FALSE;
1215 if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2)) return FALSE;
1217 if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1218 range_type = GST_TYPE_DOUBLE_RANGE;
1219 } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1220 range_type = GST_TYPE_INT_RANGE;
1225 g_value_init(value, range_type);
1226 if (range_type == GST_TYPE_DOUBLE_RANGE) {
1227 gst_value_set_double_range(value, g_value_get_double(&value1),
1228 g_value_get_double(&value2));
1230 gst_value_set_int_range(value, g_value_get_int(&value1),
1231 g_value_get_int(&value2));
1239 _gst_structure_parse_list (gchar *s, gchar **after, GValue *value, GType type)
1241 GValue list_value = { 0 };
1245 g_value_init(value, GST_TYPE_LIST);
1246 array = g_value_peek_pointer (value);
1248 if (*s != '{') return FALSE;
1251 while (g_ascii_isspace (*s)) s++;
1258 ret = _gst_structure_parse_value(s, &s, &list_value, type);
1259 if (ret == FALSE) return FALSE;
1261 g_array_append_val (array, list_value);
1263 while (g_ascii_isspace (*s)) s++;
1266 if (*s != ',') return FALSE;
1269 while (g_ascii_isspace (*s)) s++;
1271 memset (&list_value, 0, sizeof (list_value));
1272 ret = _gst_structure_parse_value(s, &s, &list_value, type);
1273 if (ret == FALSE) return FALSE;
1275 g_array_append_val (array, list_value);
1276 while (g_ascii_isspace (*s)) s++;
1286 _gst_structure_parse_simple_string (gchar *str, gchar **end)
1290 while(GST_ASCII_IS_STRING(*s)){
1300 _gst_structure_parse_field (gchar *str, gchar **after, GstStructureField *field)
1309 while(g_ascii_isspace (*s)) s++;
1311 if (!_gst_structure_parse_simple_string (s, &name_end)) return FALSE;
1314 while(g_ascii_isspace (*s)) s++;
1316 if (*s != '=') return FALSE;
1321 field->name = g_quark_from_string (name);
1324 if (!_gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1332 _gst_structure_parse_value (gchar *str, gchar **after, GValue *value,
1342 GType type = default_type;
1346 while(g_ascii_isspace (*s)) s++;
1350 type = G_TYPE_INVALID;
1353 while(g_ascii_isspace (*s)) s++;
1355 if (!_gst_structure_parse_simple_string (s, &type_end)) return FALSE;
1357 while(g_ascii_isspace (*s)) s++;
1358 if (*s != ')') return FALSE;
1360 while(g_ascii_isspace (*s)) s++;
1364 type = _gst_structure_from_abbr(type_name);
1367 if (type == G_TYPE_INVALID) return FALSE;
1370 while(g_ascii_isspace (*s)) s++;
1372 ret = _gst_structure_parse_range (s, &s, value, type);
1373 } else if (*s == '{') {
1374 ret = _gst_structure_parse_list (s, &s, value, type);
1377 if (!_gst_structure_parse_string (s, &value_end, &s)) return FALSE;
1381 if (type == G_TYPE_INVALID) {
1382 GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1386 g_value_init(value, try_types[i]);
1387 ret = gst_value_from_string (value, value_s);
1389 g_value_unset(value);
1392 g_value_init(value, type);
1394 ret = gst_value_from_string (value, value_s);
1405 * gst_structure_from_string:
1406 * @structure: a #GstStructure
1408 * Creates a #GstStructure from a string representation.
1410 * Returns: a new #GstStructure
1413 gst_structure_from_string (const gchar *string, gchar **end)
1420 GstStructure *structure;
1421 GstStructureField field = { 0 };
1424 g_return_val_if_fail(string != NULL, NULL);
1426 copy = g_strdup(string);
1430 res = _gst_structure_parse_string (r, &w, &r);
1431 if (!res) return NULL;
1433 while (g_ascii_isspace(*r)) r++;
1434 if(*r != 0 && *r != ';' && *r != ',') return NULL;
1438 structure = gst_structure_empty_new(name);
1441 while (*r && (*r != ';')){
1446 while (*r && g_ascii_isspace(*r)) r++;
1448 memset(&field,0,sizeof(field));
1449 res = _gst_structure_parse_field (r, &r, &field);
1451 gst_structure_free (structure);
1454 gst_structure_set_field(structure, &field);
1455 while (*r && g_ascii_isspace(*r)) r++;
1458 if (end) *end = (char *)string + (r - copy);
1463 _gst_structure_transform_to_string(const GValue *src_value, GValue *dest_value)
1465 g_return_if_fail(src_value != NULL);
1466 g_return_if_fail(dest_value != NULL);
1468 dest_value->data[0].v_pointer =
1469 gst_structure_to_string (src_value->data[0].v_pointer);
1473 static void _gst_structure_value_init (GValue *value)
1475 value->data[0].v_pointer = gst_structure_empty_new("");
1478 static void _gst_structure_value_free (GValue *value)
1480 gst_structure_free(value->data[0].v_pointer);
1484 static void _gst_structure_value_copy (const GValue *src, GValue *dest)
1486 dest->data[0].v_pointer = gst_structure_copy(src->data[0].v_pointer);
1489 static gpointer _gst_structure_value_peek_pointer (const GValue *value)
1491 return value->data[0].v_pointer;