branch | RCL_3 |
changeset 29 | 567bb019e3e3 |
parent 0 | 0e761a78d257 |
child 30 | 7e817e7e631c |
6:9b2c3c7a1a9c | 29:567bb019e3e3 |
---|---|
47 * convenient gst_structure_get_*() functions. |
47 * convenient gst_structure_get_*() functions. |
48 * |
48 * |
49 * Fields can be removed with gst_structure_remove_field() or |
49 * Fields can be removed with gst_structure_remove_field() or |
50 * gst_structure_remove_fields(). |
50 * gst_structure_remove_fields(). |
51 * |
51 * |
52 * Last reviewed on 2007-10-16 (0.10.15) |
52 * Strings in structures must be ASCII or UTF-8 encoded. Other encodings are |
53 * not allowed. Strings must not be empty either, but may be NULL. |
|
54 * |
|
55 * Last reviewed on 2009-06-08 (0.10.23) |
|
53 */ |
56 */ |
54 |
57 |
55 #ifdef HAVE_CONFIG_H |
58 #ifdef HAVE_CONFIG_H |
56 #include "config.h" |
59 #include "config.h" |
57 #endif |
60 #endif |
58 |
61 |
59 #include <string.h> |
62 #include <string.h> |
60 |
63 |
61 #include "gst_private.h" |
64 #include "gst_private.h" |
65 #include "gstquark.h" |
|
62 #include <gst/gst.h> |
66 #include <gst/gst.h> |
63 #include <gobject/gvaluecollector.h> |
67 #include <gobject/gvaluecollector.h> |
64 |
68 |
65 #ifdef __SYMBIAN32__ |
69 #ifdef __SYMBIAN32__ |
66 #include <glib_global.h> |
70 #include <glib_global.h> |
78 &g_array_index((structure)->fields, GstStructureField, (index)) |
82 &g_array_index((structure)->fields, GstStructureField, (index)) |
79 |
83 |
80 #define IS_MUTABLE(structure) \ |
84 #define IS_MUTABLE(structure) \ |
81 (!(structure)->parent_refcount || \ |
85 (!(structure)->parent_refcount || \ |
82 g_atomic_int_get ((structure)->parent_refcount) == 1) |
86 g_atomic_int_get ((structure)->parent_refcount) == 1) |
87 |
|
88 #define IS_TAGLIST(structure) \ |
|
89 (structure->name == GST_QUARK (TAGLIST)) |
|
83 |
90 |
84 static void gst_structure_set_field (GstStructure * structure, |
91 static void gst_structure_set_field (GstStructure * structure, |
85 GstStructureField * field); |
92 GstStructureField * field); |
86 static GstStructureField *gst_structure_get_field (const GstStructure * |
93 static GstStructureField *gst_structure_get_field (const GstStructure * |
87 structure, const gchar * fieldname); |
94 structure, const gchar * fieldname); |
119 static GstStructure * |
126 static GstStructure * |
120 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc) |
127 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc) |
121 { |
128 { |
122 GstStructure *structure; |
129 GstStructure *structure; |
123 |
130 |
124 structure = g_new0 (GstStructure, 1); |
131 structure = g_slice_new (GstStructure); |
125 structure->type = gst_structure_get_type (); |
132 structure->type = gst_structure_get_type (); |
126 structure->name = quark; |
133 structure->name = quark; |
134 structure->parent_refcount = NULL; |
|
127 structure->fields = |
135 structure->fields = |
128 g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc); |
136 g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc); |
129 |
137 |
130 return structure; |
138 return structure; |
131 } |
139 } |
132 |
140 |
133 /** |
141 /** |
148 g_return_val_if_fail (quark != 0, NULL); |
156 g_return_val_if_fail (quark != 0, NULL); |
149 |
157 |
150 return gst_structure_id_empty_new_with_size (quark, 0); |
158 return gst_structure_id_empty_new_with_size (quark, 0); |
151 } |
159 } |
152 |
160 |
161 #ifndef G_DISABLE_CHECKS |
|
153 static gboolean |
162 static gboolean |
154 gst_structure_validate_name (const gchar * name) |
163 gst_structure_validate_name (const gchar * name) |
155 { |
164 { |
156 const gchar *s; |
165 const gchar *s; |
157 |
166 |
158 g_return_val_if_fail (name != NULL, FALSE); |
167 g_return_val_if_fail (name != NULL, FALSE); |
159 |
168 |
160 /* FIXME 0.11: use g_ascii_isalpha() */ |
169 /* FIXME 0.11: use g_ascii_isalpha() */ |
161 if (!g_ascii_isalnum (*name)) { |
170 if (G_UNLIKELY (!g_ascii_isalnum (*name))) { |
162 GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s", |
171 GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s", |
163 *name, name); |
172 *name, name); |
164 return FALSE; |
173 return FALSE; |
165 } |
174 } |
166 |
175 |
167 /* FIXME 0.11: don't allow spaces */ |
176 /* FIXME 0.11: don't allow spaces */ |
168 /* FIXME: test name string more */ |
177 /* FIXME: test name string more */ |
169 s = &name[1]; |
178 s = &name[1]; |
170 while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+ ", *s) != NULL)) |
179 while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+ ", *s) != NULL)) |
171 s++; |
180 s++; |
172 if (*s != '\0') { |
181 if (G_UNLIKELY (*s != '\0')) { |
173 GST_WARNING ("Invalid character '%c' at offset %lu in structure name: %s", |
182 GST_WARNING ("Invalid character '%c' at offset %lu in structure name: %s", |
174 *s, ((gulong) s - (gulong) name), name); |
183 *s, ((gulong) s - (gulong) name), name); |
175 return FALSE; |
184 return FALSE; |
176 } |
185 } |
177 |
186 |
178 return TRUE; |
187 return TRUE; |
179 } |
188 } |
189 #endif |
|
180 |
190 |
181 /** |
191 /** |
182 * gst_structure_empty_new: |
192 * gst_structure_empty_new: |
183 * @name: name of new structure |
193 * @name: name of new structure |
184 * |
194 * |
280 #ifdef __SYMBIAN32__ |
290 #ifdef __SYMBIAN32__ |
281 EXPORT_C |
291 EXPORT_C |
282 #endif |
292 #endif |
283 |
293 |
284 void |
294 void |
285 gst_structure_set_parent_refcount (GstStructure * structure, int *refcount) |
295 gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount) |
286 { |
296 { |
287 g_return_if_fail (structure != NULL); |
297 g_return_if_fail (structure != NULL); |
288 |
298 |
289 /* if we have a parent_refcount already, we can only clear |
299 /* if we have a parent_refcount already, we can only clear |
290 * if with a NULL refcount */ |
300 * if with a NULL refcount */ |
311 GstStructure * |
321 GstStructure * |
312 gst_structure_copy (const GstStructure * structure) |
322 gst_structure_copy (const GstStructure * structure) |
313 { |
323 { |
314 GstStructure *new_structure; |
324 GstStructure *new_structure; |
315 GstStructureField *field; |
325 GstStructureField *field; |
316 guint i; |
326 guint i, len; |
317 |
327 |
318 g_return_val_if_fail (structure != NULL, NULL); |
328 g_return_val_if_fail (structure != NULL, NULL); |
319 |
329 |
320 new_structure = |
330 new_structure = |
321 gst_structure_id_empty_new_with_size (structure->name, |
331 gst_structure_id_empty_new_with_size (structure->name, |
322 structure->fields->len); |
332 structure->fields->len); |
323 |
333 |
324 for (i = 0; i < structure->fields->len; i++) { |
334 len = structure->fields->len; |
335 for (i = 0; i < len; i++) { |
|
325 GstStructureField new_field = { 0 }; |
336 GstStructureField new_field = { 0 }; |
326 |
337 |
327 field = GST_STRUCTURE_FIELD (structure, i); |
338 field = GST_STRUCTURE_FIELD (structure, i); |
328 |
339 |
329 new_field.name = field->name; |
340 new_field.name = field->name; |
347 |
358 |
348 void |
359 void |
349 gst_structure_free (GstStructure * structure) |
360 gst_structure_free (GstStructure * structure) |
350 { |
361 { |
351 GstStructureField *field; |
362 GstStructureField *field; |
352 guint i; |
363 guint i, len; |
353 |
364 |
354 g_return_if_fail (structure != NULL); |
365 g_return_if_fail (structure != NULL); |
355 g_return_if_fail (structure->parent_refcount == NULL); |
366 g_return_if_fail (structure->parent_refcount == NULL); |
356 |
367 |
357 for (i = 0; i < structure->fields->len; i++) { |
368 len = structure->fields->len; |
369 for (i = 0; i < len; i++) { |
|
358 field = GST_STRUCTURE_FIELD (structure, i); |
370 field = GST_STRUCTURE_FIELD (structure, i); |
359 |
371 |
360 if (G_IS_VALUE (&field->value)) { |
372 if (G_IS_VALUE (&field->value)) { |
361 g_value_unset (&field->value); |
373 g_value_unset (&field->value); |
362 } |
374 } |
363 } |
375 } |
364 g_array_free (structure->fields, TRUE); |
376 g_array_free (structure->fields, TRUE); |
365 #ifdef USE_POISONING |
377 #ifdef USE_POISONING |
366 memset (structure, 0xff, sizeof (GstStructure)); |
378 memset (structure, 0xff, sizeof (GstStructure)); |
367 #endif |
379 #endif |
368 g_free (structure); |
380 g_slice_free (GstStructure, structure); |
369 } |
381 } |
370 |
382 |
371 /** |
383 /** |
372 * gst_structure_get_name: |
384 * gst_structure_get_name: |
373 * @structure: a #GstStructure |
385 * @structure: a #GstStructure |
482 |
494 |
483 g_return_if_fail (structure != NULL); |
495 g_return_if_fail (structure != NULL); |
484 g_return_if_fail (G_IS_VALUE (value)); |
496 g_return_if_fail (G_IS_VALUE (value)); |
485 g_return_if_fail (IS_MUTABLE (structure)); |
497 g_return_if_fail (IS_MUTABLE (structure)); |
486 |
498 |
487 if (G_VALUE_HOLDS_STRING (value)) { |
|
488 const gchar *s; |
|
489 |
|
490 s = g_value_get_string (value); |
|
491 if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) { |
|
492 g_warning ("Trying to set string field '%s' on structure, but string is " |
|
493 "not valid UTF-8. Please file a bug.", g_quark_to_string (field)); |
|
494 return; |
|
495 } |
|
496 } |
|
497 |
|
498 gsfield.name = field; |
499 gsfield.name = field; |
499 gst_value_init_and_copy (&gsfield.value, value); |
500 gst_value_init_and_copy (&gsfield.value, value); |
500 |
501 |
501 gst_structure_set_field (structure, &gsfield); |
502 gst_structure_set_field (structure, &gsfield); |
502 } |
503 } |
538 * Variable arguments should be in the form field name, field type |
539 * Variable arguments should be in the form field name, field type |
539 * (as a GType), value(s). The last variable argument should be NULL. |
540 * (as a GType), value(s). The last variable argument should be NULL. |
540 */ |
541 */ |
541 #ifdef __SYMBIAN32__ |
542 #ifdef __SYMBIAN32__ |
542 EXPORT_C |
543 EXPORT_C |
543 #endif |
544 #endif |
544 void |
545 void |
545 gst_structure_set (GstStructure * structure, const gchar * field, ...) |
546 gst_structure_set (GstStructure * structure, const gchar * field, ...) |
546 { |
547 { |
547 va_list varargs; |
548 va_list varargs; |
548 |
549 |
582 |
583 |
583 field.name = g_quark_from_string (fieldname); |
584 field.name = g_quark_from_string (fieldname); |
584 |
585 |
585 type = va_arg (varargs, GType); |
586 type = va_arg (varargs, GType); |
586 |
587 |
587 if (type == G_TYPE_DATE) { |
588 if (G_UNLIKELY (type == G_TYPE_DATE)) { |
588 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n"); |
589 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n"); |
589 type = GST_TYPE_DATE; |
590 type = GST_TYPE_DATE; |
590 } |
591 } |
591 |
592 |
592 g_value_init (&field.value, type); |
593 g_value_init (&field.value, type); |
593 G_VALUE_COLLECT (&field.value, varargs, 0, &err); |
594 G_VALUE_COLLECT (&field.value, varargs, 0, &err); |
594 if (err) { |
595 if (G_UNLIKELY (err)) { |
595 g_critical ("%s", err); |
596 g_critical ("%s", err); |
596 return; |
597 return; |
597 } |
598 } |
598 gst_structure_set_field (structure, &field); |
599 gst_structure_set_field (structure, &field); |
599 |
600 |
660 |
661 |
661 field.name = fieldname; |
662 field.name = fieldname; |
662 |
663 |
663 type = va_arg (varargs, GType); |
664 type = va_arg (varargs, GType); |
664 |
665 |
665 if (type == G_TYPE_DATE) { |
666 if (G_UNLIKELY (type == G_TYPE_DATE)) { |
666 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n"); |
667 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n"); |
667 type = GST_TYPE_DATE; |
668 type = GST_TYPE_DATE; |
668 } |
669 } |
669 |
670 |
670 g_value_init (&field.value, type); |
671 g_value_init (&field.value, type); |
671 G_VALUE_COLLECT (&field.value, varargs, 0, &err); |
672 G_VALUE_COLLECT (&field.value, varargs, 0, &err); |
672 if (err) { |
673 if (G_UNLIKELY (err)) { |
673 g_critical ("%s", err); |
674 g_critical ("%s", err); |
674 return; |
675 return; |
675 } |
676 } |
676 gst_structure_set_field (structure, &field); |
677 gst_structure_set_field (structure, &field); |
677 |
678 |
678 fieldname = va_arg (varargs, GQuark); |
679 fieldname = va_arg (varargs, GQuark); |
679 } |
680 } |
680 } |
681 } |
681 |
682 |
683 /** |
|
684 * gst_structure_id_new: |
|
685 * @name_quark: name of new structure |
|
686 * @field_quark: the GQuark for the name of the field to set |
|
687 * @...: variable arguments |
|
688 * |
|
689 * Creates a new #GstStructure with the given name as a GQuark, followed by |
|
690 * fieldname quark, GType, argument(s) "triplets" in the same format as |
|
691 * gst_structure_id_set(). Basically a convenience wrapper around |
|
692 * gst_structure_id_empty_new() and gst_structure_id_set(). |
|
693 * |
|
694 * The last variable argument must be NULL (or 0). |
|
695 * |
|
696 * Returns: a new #GstStructure |
|
697 * |
|
698 * Since: 0.10.24 |
|
699 */ |
|
700 #ifdef __SYMBIAN32__ |
|
701 EXPORT_C |
|
702 #endif |
|
703 |
|
704 GstStructure * |
|
705 gst_structure_id_new (GQuark name_quark, GQuark field_quark, ...) |
|
706 { |
|
707 GstStructure *s; |
|
708 va_list varargs; |
|
709 |
|
710 g_return_val_if_fail (name_quark != 0, NULL); |
|
711 g_return_val_if_fail (field_quark != 0, NULL); |
|
712 |
|
713 s = gst_structure_id_empty_new (name_quark); |
|
714 |
|
715 va_start (varargs, field_quark); |
|
716 gst_structure_id_set_valist (s, field_quark, varargs); |
|
717 va_end (varargs); |
|
718 |
|
719 return s; |
|
720 } |
|
721 |
|
722 #if GST_VERSION_NANO == 1 |
|
723 #define GIT_G_WARNING g_warning |
|
724 #else |
|
725 #define GIT_G_WARNING GST_WARNING |
|
726 #endif |
|
727 |
|
682 /* If the structure currently contains a field with the same name, it is |
728 /* If the structure currently contains a field with the same name, it is |
683 * replaced with the provided field. Otherwise, the field is added to the |
729 * replaced with the provided field. Otherwise, the field is added to the |
684 * structure. The field's value is not deeply copied. |
730 * structure. The field's value is not deeply copied. |
685 */ |
731 */ |
686 static void |
732 static void |
687 gst_structure_set_field (GstStructure * structure, GstStructureField * field) |
733 gst_structure_set_field (GstStructure * structure, GstStructureField * field) |
688 { |
734 { |
689 GstStructureField *f; |
735 GstStructureField *f; |
690 guint i; |
736 guint i, len = structure->fields->len; |
691 |
737 |
692 for (i = 0; i < structure->fields->len; i++) { |
738 if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) { |
739 const gchar *s; |
|
740 |
|
741 s = g_value_get_string (&field->value); |
|
742 /* only check for NULL strings in taglists, as they are allowed in message |
|
743 * structs, e.g. error message debug strings */ |
|
744 if (G_UNLIKELY (IS_TAGLIST (structure) && (s == NULL || *s == '\0'))) { |
|
745 if (s == NULL) { |
|
746 GIT_G_WARNING ("Trying to set NULL string on field '%s' on taglist. " |
|
747 "Please file a bug.", g_quark_to_string (field->name)); |
|
748 g_value_unset (&field->value); |
|
749 return; |
|
750 } else { |
|
751 /* empty strings never make sense */ |
|
752 GIT_G_WARNING ("Trying to set empty string on taglist field '%s'. " |
|
753 "Please file a bug.", g_quark_to_string (field->name)); |
|
754 g_value_unset (&field->value); |
|
755 return; |
|
756 } |
|
757 } else if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) { |
|
758 g_warning ("Trying to set string on %s field '%s', but string is not " |
|
759 "valid UTF-8. Please file a bug.", |
|
760 IS_TAGLIST (structure) ? "taglist" : "structure", |
|
761 g_quark_to_string (field->name)); |
|
762 g_value_unset (&field->value); |
|
763 return; |
|
764 } |
|
765 } |
|
766 |
|
767 for (i = 0; i < len; i++) { |
|
693 f = GST_STRUCTURE_FIELD (structure, i); |
768 f = GST_STRUCTURE_FIELD (structure, i); |
694 |
769 |
695 if (f->name == field->name) { |
770 if (G_UNLIKELY (f->name == field->name)) { |
696 g_value_unset (&f->value); |
771 g_value_unset (&f->value); |
697 memcpy (f, field, sizeof (GstStructureField)); |
772 memcpy (f, field, sizeof (GstStructureField)); |
698 return; |
773 return; |
699 } |
774 } |
700 } |
775 } |
706 */ |
781 */ |
707 static GstStructureField * |
782 static GstStructureField * |
708 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id) |
783 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id) |
709 { |
784 { |
710 GstStructureField *field; |
785 GstStructureField *field; |
711 guint i; |
786 guint i, len; |
712 |
787 |
788 len = structure->fields->len; |
|
713 g_return_val_if_fail (structure != NULL, NULL); |
789 g_return_val_if_fail (structure != NULL, NULL); |
714 |
790 |
715 for (i = 0; i < structure->fields->len; i++) { |
791 for (i = 0; i < len; i++) { |
716 field = GST_STRUCTURE_FIELD (structure, i); |
792 field = GST_STRUCTURE_FIELD (structure, i); |
717 |
793 |
718 if (field->name == field_id) |
794 if (G_UNLIKELY (field->name == field_id)) |
719 return field; |
795 return field; |
720 } |
796 } |
721 |
797 |
722 return NULL; |
798 return NULL; |
723 } |
799 } |
807 void |
883 void |
808 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname) |
884 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname) |
809 { |
885 { |
810 GstStructureField *field; |
886 GstStructureField *field; |
811 GQuark id; |
887 GQuark id; |
812 guint i; |
888 guint i, len; |
813 |
889 |
814 g_return_if_fail (structure != NULL); |
890 g_return_if_fail (structure != NULL); |
815 g_return_if_fail (fieldname != NULL); |
891 g_return_if_fail (fieldname != NULL); |
816 g_return_if_fail (IS_MUTABLE (structure)); |
892 g_return_if_fail (IS_MUTABLE (structure)); |
817 |
893 |
818 id = g_quark_from_string (fieldname); |
894 id = g_quark_from_string (fieldname); |
819 |
895 len = structure->fields->len; |
820 for (i = 0; i < structure->fields->len; i++) { |
896 |
897 for (i = 0; i < len; i++) { |
|
821 field = GST_STRUCTURE_FIELD (structure, i); |
898 field = GST_STRUCTURE_FIELD (structure, i); |
822 |
899 |
823 if (field->name == id) { |
900 if (field->name == id) { |
824 if (G_IS_VALUE (&field->value)) { |
901 if (G_IS_VALUE (&field->value)) { |
825 g_value_unset (&field->value); |
902 g_value_unset (&field->value); |
1012 |
1089 |
1013 gboolean |
1090 gboolean |
1014 gst_structure_foreach (const GstStructure * structure, |
1091 gst_structure_foreach (const GstStructure * structure, |
1015 GstStructureForeachFunc func, gpointer user_data) |
1092 GstStructureForeachFunc func, gpointer user_data) |
1016 { |
1093 { |
1017 guint i; |
1094 guint i, len; |
1018 GstStructureField *field; |
1095 GstStructureField *field; |
1019 gboolean ret; |
1096 gboolean ret; |
1020 |
1097 |
1021 g_return_val_if_fail (structure != NULL, FALSE); |
1098 g_return_val_if_fail (structure != NULL, FALSE); |
1022 g_return_val_if_fail (func != NULL, FALSE); |
1099 g_return_val_if_fail (func != NULL, FALSE); |
1023 |
1100 |
1024 for (i = 0; i < structure->fields->len; i++) { |
1101 len = structure->fields->len; |
1102 |
|
1103 for (i = 0; i < len; i++) { |
|
1104 field = GST_STRUCTURE_FIELD (structure, i); |
|
1105 |
|
1106 ret = func (field->name, &field->value, user_data); |
|
1107 if (G_UNLIKELY (!ret)) |
|
1108 return FALSE; |
|
1109 } |
|
1110 |
|
1111 return TRUE; |
|
1112 } |
|
1113 |
|
1114 /** |
|
1115 * gst_structure_map_in_place: |
|
1116 * @structure: a #GstStructure |
|
1117 * @func: a function to call for each field |
|
1118 * @user_data: private data |
|
1119 * |
|
1120 * Calls the provided function once for each field in the #GstStructure. In |
|
1121 * contrast to gst_structure_foreach(), the function may modify but not delete the |
|
1122 * fields. The structure must be mutable. |
|
1123 * |
|
1124 * Returns: TRUE if the supplied function returns TRUE For each of the fields, |
|
1125 * FALSE otherwise. |
|
1126 */ |
|
1127 #ifdef __SYMBIAN32__ |
|
1128 EXPORT_C |
|
1129 #endif |
|
1130 |
|
1131 gboolean |
|
1132 gst_structure_map_in_place (GstStructure * structure, |
|
1133 GstStructureMapFunc func, gpointer user_data) |
|
1134 { |
|
1135 guint i, len; |
|
1136 GstStructureField *field; |
|
1137 gboolean ret; |
|
1138 |
|
1139 g_return_val_if_fail (structure != NULL, FALSE); |
|
1140 g_return_val_if_fail (IS_MUTABLE (structure), FALSE); |
|
1141 g_return_val_if_fail (func != NULL, FALSE); |
|
1142 len = structure->fields->len; |
|
1143 |
|
1144 for (i = 0; i < len; i++) { |
|
1025 field = GST_STRUCTURE_FIELD (structure, i); |
1145 field = GST_STRUCTURE_FIELD (structure, i); |
1026 |
1146 |
1027 ret = func (field->name, &field->value, user_data); |
1147 ret = func (field->name, &field->value, user_data); |
1028 if (!ret) |
1148 if (!ret) |
1029 return FALSE; |
1149 return FALSE; |
1031 |
1151 |
1032 return TRUE; |
1152 return TRUE; |
1033 } |
1153 } |
1034 |
1154 |
1035 /** |
1155 /** |
1036 * gst_structure_map_in_place: |
|
1037 * @structure: a #GstStructure |
|
1038 * @func: a function to call for each field |
|
1039 * @user_data: private data |
|
1040 * |
|
1041 * Calls the provided function once for each field in the #GstStructure. In |
|
1042 * contrast to gst_structure_foreach(), the function may modify but not delete the |
|
1043 * fields. The structure must be mutable. |
|
1044 * |
|
1045 * Returns: TRUE if the supplied function returns TRUE For each of the fields, |
|
1046 * FALSE otherwise. |
|
1047 */ |
|
1048 #ifdef __SYMBIAN32__ |
|
1049 EXPORT_C |
|
1050 #endif |
|
1051 |
|
1052 gboolean |
|
1053 gst_structure_map_in_place (GstStructure * structure, |
|
1054 GstStructureMapFunc func, gpointer user_data) |
|
1055 { |
|
1056 guint i; |
|
1057 GstStructureField *field; |
|
1058 gboolean ret; |
|
1059 |
|
1060 g_return_val_if_fail (structure != NULL, FALSE); |
|
1061 g_return_val_if_fail (IS_MUTABLE (structure), FALSE); |
|
1062 g_return_val_if_fail (func != NULL, FALSE); |
|
1063 |
|
1064 for (i = 0; i < structure->fields->len; i++) { |
|
1065 field = GST_STRUCTURE_FIELD (structure, i); |
|
1066 |
|
1067 ret = func (field->name, &field->value, user_data); |
|
1068 if (!ret) |
|
1069 return FALSE; |
|
1070 } |
|
1071 |
|
1072 return TRUE; |
|
1073 } |
|
1074 |
|
1075 /** |
|
1076 * gst_structure_has_field: |
1156 * gst_structure_has_field: |
1077 * @structure: a #GstStructure |
1157 * @structure: a #GstStructure |
1078 * @fieldname: the name of a field |
1158 * @fieldname: the name of a field |
1079 * |
1159 * |
1080 * Check if @structure contains a field named @fieldname. |
1160 * Check if @structure contains a field named @fieldname. |
1301 * |
1381 * |
1302 * Sets the date pointed to by @value corresponding to the date of the |
1382 * Sets the date pointed to by @value corresponding to the date of the |
1303 * given field. Caller is responsible for making sure the field exists |
1383 * given field. Caller is responsible for making sure the field exists |
1304 * and has the correct type. |
1384 * and has the correct type. |
1305 * |
1385 * |
1386 * On success @value will point to a newly-allocated copy of the date which |
|
1387 * should be freed with g_date_free() when no longer needed (note: this is |
|
1388 * inconsistent with e.g. gst_structure_get_string() which doesn't return a |
|
1389 * copy of the string). |
|
1390 * |
|
1306 * Returns: TRUE if the value could be set correctly. If there was no field |
1391 * Returns: TRUE if the value could be set correctly. If there was no field |
1307 * with @fieldname or the existing field did not contain a data, this function |
1392 * with @fieldname or the existing field did not contain a data, this function |
1308 * returns FALSE. |
1393 * returns FALSE. |
1309 */ |
1394 */ |
1310 #ifdef __SYMBIAN32__ |
1395 #ifdef __SYMBIAN32__ |
1326 if (field == NULL) |
1411 if (field == NULL) |
1327 return FALSE; |
1412 return FALSE; |
1328 if (!GST_VALUE_HOLDS_DATE (&field->value)) |
1413 if (!GST_VALUE_HOLDS_DATE (&field->value)) |
1329 return FALSE; |
1414 return FALSE; |
1330 |
1415 |
1416 /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */ |
|
1331 *value = g_value_dup_boxed (&field->value); |
1417 *value = g_value_dup_boxed (&field->value); |
1332 |
1418 |
1333 return TRUE; |
1419 return TRUE; |
1334 } |
1420 } |
1335 |
1421 |
1538 return TRUE; |
1624 return TRUE; |
1539 } |
1625 } |
1540 |
1626 |
1541 typedef struct _GstStructureAbbreviation |
1627 typedef struct _GstStructureAbbreviation |
1542 { |
1628 { |
1543 char *type_name; |
1629 gchar *type_name; |
1544 GType type; |
1630 GType type; |
1545 } |
1631 } |
1546 GstStructureAbbreviation; |
1632 GstStructureAbbreviation; |
1547 |
1633 |
1548 /* return a copy of an array of GstStructureAbbreviation containing all the |
1634 /* return a copy of an array of GstStructureAbbreviation containing all the |
1553 static GstStructureAbbreviation *abbrs = NULL; |
1639 static GstStructureAbbreviation *abbrs = NULL; |
1554 static gint num = 0; |
1640 static gint num = 0; |
1555 |
1641 |
1556 if (abbrs == NULL) { |
1642 if (abbrs == NULL) { |
1557 /* dynamically generate the array */ |
1643 /* dynamically generate the array */ |
1558 #ifdef __SYMBIAN32__ |
1644 #ifdef __SYMBIAN32__ |
1559 |
1645 |
1560 GstStructureAbbreviation dyn_abbrs[] = { |
1646 GstStructureAbbreviation dyn_abbrs[] = { |
1561 |
1647 |
1562 {"int", G_TYPE_INT} |
1648 {"int", G_TYPE_INT} |
1563 , |
1649 , |
1713 } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) { |
1799 } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) { |
1714 return GST_TYPE_FRACTION; |
1800 return GST_TYPE_FRACTION; |
1715 } |
1801 } |
1716 return G_VALUE_TYPE (val); |
1802 return G_VALUE_TYPE (val); |
1717 } |
1803 } |
1718 |
1804 #ifdef __SYMBIAN32__ |
1719 /* keep in sync with gstvalue.c */ |
1805 EXPORT_C |
1720 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \ |
1806 #endif |
1721 ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \ |
1807 |
1722 ((c) == '.')) |
|
1723 |
|
1724 #ifdef __SYMBIAN32__ |
|
1725 EXPORT_C |
|
1726 #endif |
|
1727 |
1808 |
1728 gboolean |
1809 gboolean |
1729 priv_gst_structure_append_to_gstring (const GstStructure * structure, |
1810 priv_gst_structure_append_to_gstring (const GstStructure * structure, |
1730 GString * s) |
1811 GString * s) |
1731 { |
1812 { |
1732 GstStructureField *field; |
1813 GstStructureField *field; |
1733 guint i; |
1814 guint i, len; |
1734 |
1815 |
1735 g_return_val_if_fail (s != NULL, FALSE); |
1816 g_return_val_if_fail (s != NULL, FALSE); |
1736 |
1817 |
1737 g_string_append (s, g_quark_to_string (structure->name)); |
1818 g_string_append (s, g_quark_to_string (structure->name)); |
1738 for (i = 0; i < structure->fields->len; i++) { |
1819 len = structure->fields->len; |
1820 for (i = 0; i < len; i++) { |
|
1739 char *t; |
1821 char *t; |
1740 GType type; |
1822 GType type; |
1741 |
1823 |
1742 field = GST_STRUCTURE_FIELD (structure, i); |
1824 field = GST_STRUCTURE_FIELD (structure, i); |
1743 |
1825 |
1748 /* FIXME: do we need to escape fieldnames? */ |
1830 /* FIXME: do we need to escape fieldnames? */ |
1749 g_string_append (s, g_quark_to_string (field->name)); |
1831 g_string_append (s, g_quark_to_string (field->name)); |
1750 g_string_append_len (s, "=(", 2); |
1832 g_string_append_len (s, "=(", 2); |
1751 g_string_append (s, gst_structure_to_abbr (type)); |
1833 g_string_append (s, gst_structure_to_abbr (type)); |
1752 g_string_append_c (s, ')'); |
1834 g_string_append_c (s, ')'); |
1753 g_string_append (s, GST_STR_NULL (t)); |
1835 g_string_append (s, t == NULL ? "NULL" : t); |
1754 g_free (t); |
1836 g_free (t); |
1755 } |
1837 } |
1756 |
1838 |
1757 g_string_append_c (s, ';'); |
1839 g_string_append_c (s, ';'); |
1758 return TRUE; |
1840 return TRUE; |
1762 * gst_structure_to_string: |
1844 * gst_structure_to_string: |
1763 * @structure: a #GstStructure |
1845 * @structure: a #GstStructure |
1764 * |
1846 * |
1765 * Converts @structure to a human-readable string representation. |
1847 * Converts @structure to a human-readable string representation. |
1766 * |
1848 * |
1849 * For debugging purposes its easier to do something like this: |
|
1850 * |[ |
|
1851 * GST_LOG ("structure is %" GST_PTR_FORMAT, structure); |
|
1852 * ]| |
|
1853 * This prints the structure in human readble form. |
|
1854 * |
|
1767 * Returns: a pointer to string allocated by g_malloc(). g_free() after |
1855 * Returns: a pointer to string allocated by g_malloc(). g_free() after |
1768 * usage. |
1856 * usage. |
1769 */ |
1857 */ |
1770 #ifdef __SYMBIAN32__ |
1858 #ifdef __SYMBIAN32__ |
1771 EXPORT_C |
1859 EXPORT_C |
1772 #endif |
1860 #endif |
1773 |
|
1774 gchar * |
1861 gchar * |
1775 gst_structure_to_string (const GstStructure * structure) |
1862 gst_structure_to_string (const GstStructure * structure) |
1776 { |
1863 { |
1777 GString *s; |
1864 GString *s; |
1778 |
1865 |
1797 * end = pointer to char behind end of string, next = pointer to start of |
1884 * end = pointer to char behind end of string, next = pointer to start of |
1798 * unread data. |
1885 * unread data. |
1799 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING |
1886 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING |
1800 */ |
1887 */ |
1801 static gboolean |
1888 static gboolean |
1802 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next) |
1889 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next, |
1890 gboolean unescape) |
|
1803 { |
1891 { |
1804 gchar *w; |
1892 gchar *w; |
1805 |
1893 |
1806 if (*s == 0) |
1894 if (*s == 0) |
1807 return FALSE; |
1895 return FALSE; |
1813 *next = *end; |
1901 *next = *end; |
1814 |
1902 |
1815 return ret; |
1903 return ret; |
1816 } |
1904 } |
1817 |
1905 |
1818 w = s; |
1906 if (unescape) { |
1819 s++; |
1907 w = s; |
1820 while (*s != '"') { |
1908 s++; |
1821 if (*s == 0) |
1909 while (*s != '"') { |
1822 return FALSE; |
1910 if (G_UNLIKELY (*s == 0)) |
1823 |
1911 return FALSE; |
1824 if (*s == '\\') { |
1912 if (G_UNLIKELY (*s == '\\')) |
1913 s++; |
|
1914 *w = *s; |
|
1915 w++; |
|
1825 s++; |
1916 s++; |
1826 } |
1917 } |
1827 |
|
1828 *w = *s; |
|
1829 w++; |
|
1830 s++; |
1918 s++; |
1831 } |
1919 } else { |
1832 s++; |
1920 /* Find the closing quotes */ |
1921 s++; |
|
1922 while (*s != '"') { |
|
1923 if (G_UNLIKELY (*s == 0)) |
|
1924 return FALSE; |
|
1925 if (G_UNLIKELY (*s == '\\')) |
|
1926 s++; |
|
1927 s++; |
|
1928 } |
|
1929 s++; |
|
1930 w = s; |
|
1931 } |
|
1833 |
1932 |
1834 *end = w; |
1933 *end = w; |
1835 *next = s; |
1934 *next = s; |
1836 |
1935 |
1837 return TRUE; |
1936 return TRUE; |
1974 static gboolean |
2073 static gboolean |
1975 gst_structure_parse_simple_string (gchar * str, gchar ** end) |
2074 gst_structure_parse_simple_string (gchar * str, gchar ** end) |
1976 { |
2075 { |
1977 char *s = str; |
2076 char *s = str; |
1978 |
2077 |
1979 while (GST_ASCII_IS_STRING (*s)) { |
2078 while (G_LIKELY (GST_ASCII_IS_STRING (*s))) { |
1980 s++; |
2079 s++; |
1981 } |
2080 } |
1982 |
2081 |
1983 *end = s; |
2082 *end = s; |
1984 |
2083 |
1997 s = str; |
2096 s = str; |
1998 |
2097 |
1999 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1]))) |
2098 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1]))) |
2000 s++; |
2099 s++; |
2001 name = s; |
2100 name = s; |
2002 if (!gst_structure_parse_simple_string (s, &name_end)) |
2101 if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &name_end))) |
2003 return FALSE; |
2102 return FALSE; |
2004 |
2103 |
2005 s = name_end; |
2104 s = name_end; |
2006 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1]))) |
2105 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1]))) |
2007 s++; |
2106 s++; |
2008 |
2107 |
2009 if (*s != '=') |
2108 if (G_UNLIKELY (*s != '=')) |
2010 return FALSE; |
2109 return FALSE; |
2011 s++; |
2110 s++; |
2012 |
2111 |
2013 c = *name_end; |
2112 c = *name_end; |
2014 *name_end = 0; |
2113 *name_end = '\0'; |
2015 field->name = g_quark_from_string (name); |
2114 field->name = g_quark_from_string (name); |
2016 *name_end = c; |
2115 *name_end = c; |
2017 |
2116 |
2018 if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID)) |
2117 if (G_UNLIKELY (!gst_structure_parse_value (s, &s, &field->value, |
2118 G_TYPE_INVALID))) |
|
2019 return FALSE; |
2119 return FALSE; |
2020 |
2120 |
2021 *after = s; |
2121 *after = s; |
2022 return TRUE; |
2122 return TRUE; |
2023 } |
2123 } |
2036 #ifdef __SYMBIAN32__ |
2136 #ifdef __SYMBIAN32__ |
2037 int i; |
2137 int i; |
2038 #endif |
2138 #endif |
2039 GType type = default_type; |
2139 GType type = default_type; |
2040 |
2140 |
2041 |
|
2042 s = str; |
2141 s = str; |
2043 while (g_ascii_isspace (*s)) |
2142 while (g_ascii_isspace (*s)) |
2044 s++; |
2143 s++; |
2045 |
2144 |
2046 /* check if there's a (type_name) 'cast' */ |
2145 /* check if there's a (type_name) 'cast' */ |
2047 type_name = NULL; |
2146 type_name = NULL; |
2048 if (*s == '(') { |
2147 if (*s == '(') { |
2049 type = G_TYPE_INVALID; |
|
2050 |
|
2051 s++; |
2148 s++; |
2052 while (g_ascii_isspace (*s)) |
2149 while (g_ascii_isspace (*s)) |
2053 s++; |
2150 s++; |
2054 type_name = s; |
2151 type_name = s; |
2055 if (!gst_structure_parse_simple_string (s, &type_end)) |
2152 if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &type_end))) |
2056 return FALSE; |
2153 return FALSE; |
2057 s = type_end; |
2154 s = type_end; |
2058 while (g_ascii_isspace (*s)) |
2155 while (g_ascii_isspace (*s)) |
2059 s++; |
2156 s++; |
2060 if (*s != ')') |
2157 if (G_UNLIKELY (*s != ')')) |
2061 return FALSE; |
2158 return FALSE; |
2062 s++; |
2159 s++; |
2063 while (g_ascii_isspace (*s)) |
2160 while (g_ascii_isspace (*s)) |
2064 s++; |
2161 s++; |
2065 |
2162 |
2066 c = *type_end; |
2163 c = *type_end; |
2067 *type_end = 0; |
2164 *type_end = 0; |
2068 type = gst_structure_gtype_from_abbr (type_name); |
2165 type = gst_structure_gtype_from_abbr (type_name); |
2069 *type_end = c; |
2166 *type_end = c; |
2070 |
2167 |
2071 if (type == G_TYPE_INVALID) |
2168 if (G_UNLIKELY (type == G_TYPE_INVALID)) |
2072 return FALSE; |
2169 return FALSE; |
2073 } |
2170 } |
2074 |
2171 |
2075 while (g_ascii_isspace (*s)) |
2172 while (g_ascii_isspace (*s)) |
2076 s++; |
2173 s++; |
2080 ret = gst_structure_parse_list (s, &s, value, type); |
2177 ret = gst_structure_parse_list (s, &s, value, type); |
2081 } else if (*s == '<') { |
2178 } else if (*s == '<') { |
2082 ret = gst_structure_parse_array (s, &s, value, type); |
2179 ret = gst_structure_parse_array (s, &s, value, type); |
2083 } else { |
2180 } else { |
2084 value_s = s; |
2181 value_s = s; |
2085 if (!gst_structure_parse_string (s, &value_end, &s)) |
2182 |
2086 return FALSE; |
2183 if (G_UNLIKELY (type == G_TYPE_INVALID)) { |
2087 |
|
2088 c = *value_end; |
|
2089 *value_end = 0; |
|
2090 if (type == G_TYPE_INVALID) { |
|
2091 #ifdef __SYMBIAN32__ |
2184 #ifdef __SYMBIAN32__ |
2092 GType try_types[] = |
2185 GType try_types[] = |
2093 { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_INVALID, G_TYPE_STRING }; |
2186 { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_INVALID, G_TYPE_STRING }; |
2094 try_types[2] =GST_TYPE_FRACTION; |
2187 try_types[2] =GST_TYPE_FRACTION; |
2095 |
2188 |
2097 GType try_types[] = |
2190 GType try_types[] = |
2098 { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_STRING }; |
2191 { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_STRING }; |
2099 |
2192 |
2100 int i; |
2193 int i; |
2101 #endif |
2194 #endif |
2195 if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s, TRUE))) |
|
2196 return FALSE; |
|
2197 /* Set NULL terminator for deserialization */ |
|
2198 c = *value_end; |
|
2199 *value_end = '\0'; |
|
2200 |
|
2102 for (i = 0; i < G_N_ELEMENTS (try_types); i++) { |
2201 for (i = 0; i < G_N_ELEMENTS (try_types); i++) { |
2103 g_value_init (value, try_types[i]); |
2202 g_value_init (value, try_types[i]); |
2104 ret = gst_value_deserialize (value, value_s); |
2203 ret = gst_value_deserialize (value, value_s); |
2105 if (ret) |
2204 if (ret) |
2106 break; |
2205 break; |
2107 g_value_unset (value); |
2206 g_value_unset (value); |
2108 } |
2207 } |
2109 } else { |
2208 } else { |
2110 g_value_init (value, type); |
2209 g_value_init (value, type); |
2111 |
2210 |
2211 if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s, |
|
2212 (type != G_TYPE_STRING)))) |
|
2213 return FALSE; |
|
2214 /* Set NULL terminator for deserialization */ |
|
2215 c = *value_end; |
|
2216 *value_end = '\0'; |
|
2217 |
|
2112 ret = gst_value_deserialize (value, value_s); |
2218 ret = gst_value_deserialize (value, value_s); |
2219 if (G_UNLIKELY (!ret)) |
|
2220 g_value_unset (value); |
|
2113 } |
2221 } |
2114 *value_end = c; |
2222 *value_end = c; |
2115 } |
2223 } |
2116 |
2224 |
2117 *after = s; |
2225 *after = s; |
2142 char *copy; |
2250 char *copy; |
2143 char *w; |
2251 char *w; |
2144 char *r; |
2252 char *r; |
2145 char save; |
2253 char save; |
2146 GstStructure *structure = NULL; |
2254 GstStructure *structure = NULL; |
2147 GstStructureField field = { 0 }; |
2255 GstStructureField field; |
2148 |
2256 |
2149 g_return_val_if_fail (string != NULL, NULL); |
2257 g_return_val_if_fail (string != NULL, NULL); |
2150 |
2258 |
2151 copy = g_strdup (string); |
2259 copy = g_strdup (string); |
2152 r = copy; |
2260 r = copy; |
2155 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2263 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2156 && g_ascii_isspace (r[1])))) |
2264 && g_ascii_isspace (r[1])))) |
2157 r++; |
2265 r++; |
2158 |
2266 |
2159 name = r; |
2267 name = r; |
2160 if (!gst_structure_parse_string (r, &w, &r)) { |
2268 if (G_UNLIKELY (!gst_structure_parse_string (r, &w, &r, TRUE))) { |
2161 GST_WARNING ("Failed to parse structure string"); |
2269 GST_WARNING ("Failed to parse structure string"); |
2162 goto error; |
2270 goto error; |
2163 } |
2271 } |
2164 |
2272 |
2165 save = *w; |
2273 save = *w; |
2166 *w = 0; |
2274 *w = '\0'; |
2167 structure = gst_structure_empty_new (name); |
2275 structure = gst_structure_empty_new (name); |
2168 *w = save; |
2276 *w = save; |
2169 |
2277 |
2170 if (structure == NULL) |
2278 if (G_UNLIKELY (structure == NULL)) |
2171 goto error; |
2279 goto error; |
2172 |
2280 |
2173 do { |
2281 do { |
2174 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2282 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2175 && g_ascii_isspace (r[1])))) |
2283 && g_ascii_isspace (r[1])))) |
2181 } |
2289 } |
2182 if (*r == '\0') { |
2290 if (*r == '\0') { |
2183 /* accept \0 as end delimiter */ |
2291 /* accept \0 as end delimiter */ |
2184 break; |
2292 break; |
2185 } |
2293 } |
2186 if (*r != ',') { |
2294 if (G_UNLIKELY (*r != ',')) { |
2187 GST_WARNING ("Failed to find delimiter, r=%s", r); |
2295 GST_WARNING ("Failed to find delimiter, r=%s", r); |
2188 goto error; |
2296 goto error; |
2189 } |
2297 } |
2190 r++; |
2298 r++; |
2191 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2299 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\' |
2192 && g_ascii_isspace (r[1])))) |
2300 && g_ascii_isspace (r[1])))) |
2193 r++; |
2301 r++; |
2194 |
2302 |
2195 memset (&field, 0, sizeof (field)); |
2303 memset (&field, 0, sizeof (field)); |
2196 if (!gst_structure_parse_field (r, &r, &field)) |
2304 if (G_UNLIKELY (!gst_structure_parse_field (r, &r, &field))) |
2197 goto error; |
2305 goto error; |
2198 gst_structure_set_field (structure, &field); |
2306 gst_structure_set_field (structure, &field); |
2199 |
|
2200 } while (TRUE); |
2307 } while (TRUE); |
2201 |
2308 |
2202 if (end) |
2309 if (end) |
2203 *end = (char *) string + (r - copy); |
2310 *end = (char *) string + (r - copy); |
2204 else if (*r) |
2311 else if (*r) |
2481 return TRUE; |
2588 return TRUE; |
2482 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) { |
2589 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) { |
2483 const GValue *list_value; |
2590 const GValue *list_value; |
2484 int i, n; |
2591 int i, n; |
2485 const GValue *best = NULL; |
2592 const GValue *best = NULL; |
2486 GValue best_diff = { 0 }; |
2593 gdouble target; |
2487 GValue cur_diff = { 0 }; |
2594 gdouble cur_diff; |
2488 GValue target = { 0 }; |
2595 gdouble best_diff = G_MAXDOUBLE; |
2489 gboolean res = FALSE; |
2596 |
2490 |
2597 target = (gdouble) target_numerator / (gdouble) target_denominator; |
2491 g_value_init (&best_diff, GST_TYPE_FRACTION); |
2598 |
2492 g_value_init (&cur_diff, GST_TYPE_FRACTION); |
2599 GST_DEBUG ("target %g, best %g", target, best_diff); |
2493 g_value_init (&target, GST_TYPE_FRACTION); |
|
2494 |
|
2495 gst_value_set_fraction (&target, target_numerator, target_denominator); |
|
2496 |
2600 |
2497 best = NULL; |
2601 best = NULL; |
2498 |
2602 |
2499 n = gst_value_list_get_size (value); |
2603 n = gst_value_list_get_size (value); |
2500 for (i = 0; i < n; i++) { |
2604 for (i = 0; i < n; i++) { |
2501 list_value = gst_value_list_get_value (value, i); |
2605 list_value = gst_value_list_get_value (value, i); |
2502 if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) { |
2606 if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) { |
2503 |
2607 gint num, denom; |
2504 if (gst_value_compare (list_value, &target) == GST_VALUE_LESS_THAN) |
2608 gdouble list_double; |
2505 gst_value_fraction_subtract (&cur_diff, &target, list_value); |
2609 |
2506 else |
2610 num = gst_value_get_fraction_numerator (list_value); |
2507 gst_value_fraction_subtract (&cur_diff, list_value, &target); |
2611 denom = gst_value_get_fraction_denominator (list_value); |
2508 |
2612 |
2509 if (!best |
2613 list_double = ((gdouble) num / (gdouble) denom); |
2510 || gst_value_compare (&cur_diff, |
2614 cur_diff = target - list_double; |
2511 &best_diff) == GST_VALUE_LESS_THAN) { |
2615 |
2616 GST_DEBUG ("curr diff %g, list %g", cur_diff, list_double); |
|
2617 |
|
2618 if (cur_diff < 0) |
|
2619 cur_diff = -cur_diff; |
|
2620 |
|
2621 if (!best || cur_diff < best_diff) { |
|
2622 GST_DEBUG ("new best %g", list_double); |
|
2512 best = list_value; |
2623 best = list_value; |
2513 g_value_copy (&cur_diff, &best_diff); |
2624 best_diff = cur_diff; |
2514 } |
2625 } |
2515 } |
2626 } |
2516 } |
2627 } |
2517 if (best != NULL) { |
2628 if (best != NULL) { |
2518 gst_structure_set_value (structure, field_name, best); |
2629 gst_structure_set_value (structure, field_name, best); |
2519 res = TRUE; |
2630 return TRUE; |
2520 } |
2631 } |
2521 g_value_unset (&best_diff); |
2632 } |
2522 g_value_unset (&cur_diff); |
2633 |
2523 g_value_unset (&target); |
|
2524 return res; |
|
2525 } |
|
2526 return FALSE; |
2634 return FALSE; |
2527 } |
2635 } |
2636 |
|
2637 /* our very own version of G_VALUE_LCOPY that allows NULL return locations |
|
2638 * (useful for message parsing functions where the return location is user |
|
2639 * supplied and the user may pass NULL if the value isn't of interest) */ |
|
2640 #define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname) \ |
|
2641 G_STMT_START { \ |
|
2642 const GValue *_value = (value); \ |
|
2643 guint _flags = (flags); \ |
|
2644 GType _value_type = G_VALUE_TYPE (_value); \ |
|
2645 GTypeValueTable *_vtable = g_type_value_table_peek (_value_type); \ |
|
2646 gchar *_lcopy_format = _vtable->lcopy_format; \ |
|
2647 GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \ |
|
2648 guint _n_values = 0; \ |
|
2649 \ |
|
2650 while (*_lcopy_format != '\0') { \ |
|
2651 g_assert (*_lcopy_format == G_VALUE_COLLECT_POINTER); \ |
|
2652 _cvalues[_n_values++].v_pointer = va_arg ((var_args), gpointer); \ |
|
2653 _lcopy_format++; \ |
|
2654 } \ |
|
2655 if (_n_values == 2 && !!_cvalues[0].v_pointer != !!_cvalues[1].v_pointer) { \ |
|
2656 *(__error) = g_strdup_printf ("either all or none of the return " \ |
|
2657 "locations for field '%s' need to be NULL", fieldname); \ |
|
2658 } else if (_cvalues[0].v_pointer != NULL) { \ |
|
2659 *(__error) = _vtable->lcopy_value (_value, _n_values, _cvalues, _flags); \ |
|
2660 } \ |
|
2661 } G_STMT_END |
|
2662 |
|
2663 /** |
|
2664 * gst_structure_get_valist: |
|
2665 * @structure: a #GstStructure |
|
2666 * @first_fieldname: the name of the first field to read |
|
2667 * @args: variable arguments |
|
2668 * |
|
2669 * Parses the variable arguments and reads fields from @structure accordingly. |
|
2670 * valist-variant of gst_structure_get(). Look at the documentation of |
|
2671 * gst_structure_get() for more details. |
|
2672 * |
|
2673 * Returns: TRUE, or FALSE if there was a problem reading any of the fields |
|
2674 * |
|
2675 * Since: 0.10.24 |
|
2676 */ |
|
2677 #ifdef __SYMBIAN32__ |
|
2678 EXPORT_C |
|
2679 #endif |
|
2680 |
|
2681 gboolean |
|
2682 gst_structure_get_valist (GstStructure * structure, |
|
2683 const char *first_fieldname, va_list args) |
|
2684 { |
|
2685 const char *field_name; |
|
2686 GType expected_type = G_TYPE_INVALID; |
|
2687 |
|
2688 g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE); |
|
2689 g_return_val_if_fail (first_fieldname != NULL, FALSE); |
|
2690 |
|
2691 field_name = first_fieldname; |
|
2692 while (field_name) { |
|
2693 const GValue *val = NULL; |
|
2694 gchar *err = NULL; |
|
2695 |
|
2696 expected_type = va_arg (args, GType); |
|
2697 |
|
2698 val = gst_structure_get_value (structure, field_name); |
|
2699 |
|
2700 if (val == NULL) |
|
2701 goto no_such_field; |
|
2702 |
|
2703 if (G_VALUE_TYPE (val) != expected_type) |
|
2704 goto wrong_type; |
|
2705 |
|
2706 GST_VALUE_LCOPY (val, args, 0, &err, field_name); |
|
2707 if (err) { |
|
2708 g_warning ("%s: %s", G_STRFUNC, err); |
|
2709 g_free (err); |
|
2710 return FALSE; |
|
2711 } |
|
2712 |
|
2713 field_name = va_arg (args, const gchar *); |
|
2714 } |
|
2715 |
|
2716 return TRUE; |
|
2717 |
|
2718 /* ERRORS */ |
|
2719 no_such_field: |
|
2720 { |
|
2721 GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT, |
|
2722 field_name, structure); |
|
2723 return FALSE; |
|
2724 } |
|
2725 wrong_type: |
|
2726 { |
|
2727 GST_WARNING ("Expected field '%s' in structure to be of type '%s', but " |
|
2728 "field was of type '%s': %" GST_PTR_FORMAT, field_name, |
|
2729 GST_STR_NULL (g_type_name (expected_type)), |
|
2730 G_VALUE_TYPE_NAME (gst_structure_get_value (structure, field_name)), |
|
2731 structure); |
|
2732 return FALSE; |
|
2733 } |
|
2734 } |
|
2735 |
|
2736 /** |
|
2737 * gst_structure_id_get_valist: |
|
2738 * @structure: a #GstStructure |
|
2739 * @first_field_id: the quark of the first field to read |
|
2740 * @args: variable arguments |
|
2741 * |
|
2742 * Parses the variable arguments and reads fields from @structure accordingly. |
|
2743 * valist-variant of gst_structure_id_get(). Look at the documentation of |
|
2744 * gst_structure_id_get() for more details. |
|
2745 * |
|
2746 * Returns: TRUE, or FALSE if there was a problem reading any of the fields |
|
2747 * |
|
2748 * Since: 0.10.24 |
|
2749 */ |
|
2750 #ifdef __SYMBIAN32__ |
|
2751 EXPORT_C |
|
2752 #endif |
|
2753 |
|
2754 gboolean |
|
2755 gst_structure_id_get_valist (GstStructure * structure, GQuark first_field_id, |
|
2756 va_list args) |
|
2757 { |
|
2758 GQuark field_id; |
|
2759 GType expected_type = G_TYPE_INVALID; |
|
2760 |
|
2761 g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE); |
|
2762 g_return_val_if_fail (first_field_id != 0, FALSE); |
|
2763 |
|
2764 field_id = first_field_id; |
|
2765 while (field_id) { |
|
2766 const GValue *val = NULL; |
|
2767 gchar *err = NULL; |
|
2768 |
|
2769 expected_type = va_arg (args, GType); |
|
2770 |
|
2771 val = gst_structure_id_get_value (structure, field_id); |
|
2772 |
|
2773 if (val == NULL) |
|
2774 goto no_such_field; |
|
2775 |
|
2776 if (G_VALUE_TYPE (val) != expected_type) |
|
2777 goto wrong_type; |
|
2778 |
|
2779 GST_VALUE_LCOPY (val, args, 0, &err, g_quark_to_string (field_id)); |
|
2780 if (err) { |
|
2781 g_warning ("%s: %s", G_STRFUNC, err); |
|
2782 g_free (err); |
|
2783 return FALSE; |
|
2784 } |
|
2785 |
|
2786 field_id = va_arg (args, GQuark); |
|
2787 } |
|
2788 |
|
2789 return TRUE; |
|
2790 |
|
2791 /* ERRORS */ |
|
2792 no_such_field: |
|
2793 { |
|
2794 GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT, |
|
2795 GST_STR_NULL (g_quark_to_string (field_id)), structure); |
|
2796 return FALSE; |
|
2797 } |
|
2798 wrong_type: |
|
2799 { |
|
2800 GST_WARNING ("Expected field '%s' in structure to be of type '%s', but " |
|
2801 "field was of type '%s': %" GST_PTR_FORMAT, |
|
2802 g_quark_to_string (field_id), |
|
2803 GST_STR_NULL (g_type_name (expected_type)), |
|
2804 G_VALUE_TYPE_NAME (gst_structure_id_get_value (structure, field_id)), |
|
2805 structure); |
|
2806 return FALSE; |
|
2807 } |
|
2808 } |
|
2809 |
|
2810 /** |
|
2811 * gst_structure_get: |
|
2812 * @structure: a #GstStructure |
|
2813 * @first_fieldname: the name of the first field to read |
|
2814 * @...: variable arguments |
|
2815 * |
|
2816 * Parses the variable arguments and reads fields from @structure accordingly. |
|
2817 * Variable arguments should be in the form field name, field type |
|
2818 * (as a GType), pointer(s) to a variable(s) to hold the return value(s). |
|
2819 * The last variable argument should be NULL. |
|
2820 * |
|
2821 * For refcounted (mini)objects you will acquire your own reference which |
|
2822 * you must release with a suitable _unref() when no longer needed. For |
|
2823 * strings and boxed types you will acquire a copy which you will need to |
|
2824 * release with either g_free() or the suiteable function for the boxed type. |
|
2825 * |
|
2826 * Returns: FALSE if there was a problem reading any of the fields (e.g. |
|
2827 * because the field requested did not exist, or was of a type other |
|
2828 * than the type specified), otherwise TRUE. |
|
2829 * |
|
2830 * Since: 0.10.24 |
|
2831 */ |
|
2832 #ifdef __SYMBIAN32__ |
|
2833 EXPORT_C |
|
2834 #endif |
|
2835 |
|
2836 gboolean |
|
2837 gst_structure_get (GstStructure * structure, const char *first_fieldname, ...) |
|
2838 { |
|
2839 gboolean ret; |
|
2840 va_list args; |
|
2841 |
|
2842 g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE); |
|
2843 g_return_val_if_fail (first_fieldname != NULL, FALSE); |
|
2844 |
|
2845 va_start (args, first_fieldname); |
|
2846 ret = gst_structure_get_valist (structure, first_fieldname, args); |
|
2847 va_end (args); |
|
2848 |
|
2849 return ret; |
|
2850 } |
|
2851 |
|
2852 /** |
|
2853 * gst_structure_id_get: |
|
2854 * @structure: a #GstStructure |
|
2855 * @first_field_id: the quark of the first field to read |
|
2856 * @...: variable arguments |
|
2857 * |
|
2858 * Parses the variable arguments and reads fields from @structure accordingly. |
|
2859 * Variable arguments should be in the form field id quark, field type |
|
2860 * (as a GType), pointer(s) to a variable(s) to hold the return value(s). |
|
2861 * The last variable argument should be NULL (technically it should be a |
|
2862 * 0 quark, but we require NULL so compilers that support it can check for |
|
2863 * the NULL terminator and warn if it's not there). |
|
2864 * |
|
2865 * This function is just like gst_structure_get() only that it is slightly |
|
2866 * more efficient since it saves the string-to-quark lookup in the global |
|
2867 * quark hashtable. |
|
2868 * |
|
2869 * For refcounted (mini)objects you will acquire your own reference which |
|
2870 * you must release with a suitable _unref() when no longer needed. For |
|
2871 * strings and boxed types you will acquire a copy which you will need to |
|
2872 * release with either g_free() or the suiteable function for the boxed type. |
|
2873 * |
|
2874 * Returns: FALSE if there was a problem reading any of the fields (e.g. |
|
2875 * because the field requested did not exist, or was of a type other |
|
2876 * than the type specified), otherwise TRUE. |
|
2877 * |
|
2878 * Since: 0.10.24 |
|
2879 */ |
|
2880 #ifdef __SYMBIAN32__ |
|
2881 EXPORT_C |
|
2882 #endif |
|
2883 |
|
2884 gboolean |
|
2885 gst_structure_id_get (GstStructure * structure, GQuark first_field_id, ...) |
|
2886 { |
|
2887 gboolean ret; |
|
2888 va_list args; |
|
2889 |
|
2890 g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE); |
|
2891 g_return_val_if_fail (first_field_id != 0, FALSE); |
|
2892 |
|
2893 va_start (args, first_field_id); |
|
2894 ret = gst_structure_id_get_valist (structure, first_field_id, args); |
|
2895 va_end (args); |
|
2896 |
|
2897 return ret; |
|
2898 } |