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 */
22 /**
23 * SECTION:gststructure
24 * @short_description: Generic structure containing fields of names and values
25 * @see_also: #GstCaps, #GstMessage, #GstEvent, #GstQuery
26 *
27 * A #GstStructure is a collection of key/value pairs. The keys are expressed
28 * as GQuarks and the values can be of any GType.
29 *
30 * In addition to the key/value pairs, a #GstStructure also has a name. The name
31 * starts with a letter and can be folled by letters, numbers and any of "/-_.:".
32 *
33 * #GstStructure is used by various GStreamer subsystems to store information
34 * in a flexible and extensible way. A #GstStructure does not have a refcount
35 * because it usually is part of a higher level object such as #GstCaps. It
36 * provides a means to enforce mutability using the refcount of the parent
37 * with the gst_structure_set_parent_refcount() method.
38 *
39 * A #GstStructure can be created with gst_structure_empty_new() or
40 * gst_structure_new(), which both take a name and an optional set of
41 * key/value pairs along with the types of the values.
42 *
43 * Field values can be changed with gst_structure_set_value() or
44 * gst_structure_set().
45 *
46 * Field values can be retrieved with gst_structure_get_value() or the more
47 * convenient gst_structure_get_*() functions.
48 *
49 * Fields can be removed with gst_structure_remove_field() or
50 * gst_structure_remove_fields().
51 *
52 * Last reviewed on 2007-10-16 (0.10.15)
53 */
55 #ifdef HAVE_CONFIG_H
56 #include "config.h"
57 #endif
59 #include <string.h>
61 #include "gst_private.h"
62 #include <gst/gst.h>
63 #include <gobject/gvaluecollector.h>
65 typedef struct _GstStructureField GstStructureField;
67 struct _GstStructureField
68 {
69 GQuark name;
70 GValue value;
71 };
73 #define GST_STRUCTURE_FIELD(structure, index) \
74 &g_array_index((structure)->fields, GstStructureField, (index))
76 #define IS_MUTABLE(structure) \
77 (!(structure)->parent_refcount || \
78 g_atomic_int_get ((structure)->parent_refcount) == 1)
80 static void gst_structure_set_field (GstStructure * structure,
81 GstStructureField * field);
82 static GstStructureField *gst_structure_get_field (const GstStructure *
83 structure, const gchar * fieldname);
84 static GstStructureField *gst_structure_id_get_field (const GstStructure *
85 structure, GQuark field);
86 static void gst_structure_transform_to_string (const GValue * src_value,
87 GValue * dest_value);
88 static GstStructure *gst_structure_copy_conditional (const GstStructure *
89 structure);
90 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
91 GValue * value, GType default_type);
92 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
94 GType
95 gst_structure_get_type (void)
96 {
97 static GType gst_structure_type = 0;
99 if (G_UNLIKELY (gst_structure_type == 0)) {
100 gst_structure_type = g_boxed_type_register_static ("GstStructure",
101 (GBoxedCopyFunc) gst_structure_copy_conditional,
102 (GBoxedFreeFunc) gst_structure_free);
104 g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
105 gst_structure_transform_to_string);
106 }
108 return gst_structure_type;
109 }
111 static GstStructure *
112 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
113 {
114 GstStructure *structure;
116 structure = g_new0 (GstStructure, 1);
117 structure->type = gst_structure_get_type ();
118 structure->name = quark;
119 structure->fields =
120 g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc);
122 return structure;
123 }
125 /**
126 * gst_structure_id_empty_new:
127 * @quark: name of new structure
128 *
129 * Creates a new, empty #GstStructure with the given name as a GQuark.
130 *
131 * Returns: a new, empty #GstStructure
132 */
133 GstStructure *
134 gst_structure_id_empty_new (GQuark quark)
135 {
136 g_return_val_if_fail (quark != 0, NULL);
138 return gst_structure_id_empty_new_with_size (quark, 0);
139 }
141 static gboolean
142 gst_structure_validate_name (const gchar * name)
143 {
144 const gchar *s;
146 g_return_val_if_fail (name != NULL, FALSE);
148 /* FIXME 0.11: use g_ascii_isalpha() */
149 if (!g_ascii_isalnum (*name)) {
150 GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s",
151 *name, name);
152 return FALSE;
153 }
155 /* FIXME 0.11: don't allow spaces */
156 /* FIXME: test name string more */
157 s = &name[1];
158 while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+ ", *s) != NULL))
159 s++;
160 if (*s != '\0') {
161 GST_WARNING ("Invalid character '%c' at offset %lu in structure name: %s",
162 *s, ((gulong) s - (gulong) name), name);
163 return FALSE;
164 }
166 return TRUE;
167 }
169 /**
170 * gst_structure_empty_new:
171 * @name: name of new structure
172 *
173 * Creates a new, empty #GstStructure with the given @name.
174 *
175 * See gst_structure_set_name() for constraints on the @name parameter.
176 *
177 * Returns: a new, empty #GstStructure
178 */
179 GstStructure *
180 gst_structure_empty_new (const gchar * name)
181 {
182 g_return_val_if_fail (gst_structure_validate_name (name), NULL);
184 return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
185 }
187 /**
188 * gst_structure_new:
189 * @name: name of new structure
190 * @firstfield: name of first field to set
191 * @...: additional arguments
192 *
193 * Creates a new #GstStructure with the given name. Parses the
194 * list of variable arguments and sets fields to the values listed.
195 * Variable arguments should be passed as field name, field type,
196 * and value. Last variable argument should be NULL.
197 *
198 * Returns: a new #GstStructure
199 */
200 GstStructure *
201 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
202 {
203 GstStructure *structure;
204 va_list varargs;
206 g_return_val_if_fail (name != NULL, NULL);
208 va_start (varargs, firstfield);
210 structure = gst_structure_new_valist (name, firstfield, varargs);
212 va_end (varargs);
214 return structure;
215 }
217 /**
218 * gst_structure_new_valist:
219 * @name: name of new structure
220 * @firstfield: name of first field to set
221 * @varargs: variable argument list
222 *
223 * Creates a new #GstStructure with the given @name. Structure fields
224 * are set according to the varargs in a manner similar to
225 * gst_structure_new().
226 *
227 * See gst_structure_set_name() for constraints on the @name parameter.
228 *
229 * Returns: a new #GstStructure
230 */
231 GstStructure *
232 gst_structure_new_valist (const gchar * name,
233 const gchar * firstfield, va_list varargs)
234 {
235 GstStructure *structure;
237 g_return_val_if_fail (name != NULL, NULL);
239 structure = gst_structure_empty_new (name);
241 if (structure)
242 gst_structure_set_valist (structure, firstfield, varargs);
244 return structure;
245 }
247 /**
248 * gst_structure_set_parent_refcount:
249 * @structure: a #GstStructure
250 * @refcount: a pointer to the parent's refcount
251 *
252 * Sets the parent_refcount field of #GstStructure. This field is used to
253 * determine whether a structure is mutable or not. This function should only be
254 * called by code implementing parent objects of #GstStructure, as described in
255 * the MT Refcounting section of the design documents.
256 */
257 void
258 gst_structure_set_parent_refcount (GstStructure * structure, int *refcount)
259 {
260 g_return_if_fail (structure != NULL);
262 /* if we have a parent_refcount already, we can only clear
263 * if with a NULL refcount */
264 if (structure->parent_refcount)
265 g_return_if_fail (refcount == NULL);
266 else
267 g_return_if_fail (refcount != NULL);
269 structure->parent_refcount = refcount;
270 }
272 /**
273 * gst_structure_copy:
274 * @structure: a #GstStructure to duplicate
275 *
276 * Duplicates a #GstStructure and all its fields and values.
277 *
278 * Returns: a new #GstStructure.
279 */
280 GstStructure *
281 gst_structure_copy (const GstStructure * structure)
282 {
283 GstStructure *new_structure;
284 GstStructureField *field;
285 guint i;
287 g_return_val_if_fail (structure != NULL, NULL);
289 new_structure =
290 gst_structure_id_empty_new_with_size (structure->name,
291 structure->fields->len);
293 for (i = 0; i < structure->fields->len; i++) {
294 GstStructureField new_field = { 0 };
296 field = GST_STRUCTURE_FIELD (structure, i);
298 new_field.name = field->name;
299 gst_value_init_and_copy (&new_field.value, &field->value);
300 g_array_append_val (new_structure->fields, new_field);
301 }
303 return new_structure;
304 }
306 /**
307 * gst_structure_free:
308 * @structure: the #GstStructure to free
309 *
310 * Frees a #GstStructure and all its fields and values. The structure must not
311 * have a parent when this function is called.
312 */
313 void
314 gst_structure_free (GstStructure * structure)
315 {
316 GstStructureField *field;
317 guint i;
319 g_return_if_fail (structure != NULL);
320 g_return_if_fail (structure->parent_refcount == NULL);
322 for (i = 0; i < structure->fields->len; i++) {
323 field = GST_STRUCTURE_FIELD (structure, i);
325 if (G_IS_VALUE (&field->value)) {
326 g_value_unset (&field->value);
327 }
328 }
329 g_array_free (structure->fields, TRUE);
330 #ifdef USE_POISONING
331 memset (structure, 0xff, sizeof (GstStructure));
332 #endif
333 g_free (structure);
334 }
336 /**
337 * gst_structure_get_name:
338 * @structure: a #GstStructure
339 *
340 * Get the name of @structure as a string.
341 *
342 * Returns: the name of the structure.
343 */
344 const gchar *
345 gst_structure_get_name (const GstStructure * structure)
346 {
347 g_return_val_if_fail (structure != NULL, NULL);
349 return g_quark_to_string (structure->name);
350 }
352 /**
353 * gst_structure_has_name:
354 * @structure: a #GstStructure
355 * @name: structure name to check for
356 *
357 * Checks if the structure has the given name
358 *
359 * Returns: TRUE if @name matches the name of the structure.
360 */
361 gboolean
362 gst_structure_has_name (const GstStructure * structure, const gchar * name)
363 {
364 const gchar *structure_name;
366 g_return_val_if_fail (structure != NULL, FALSE);
367 g_return_val_if_fail (name != NULL, FALSE);
369 /* getting the string is cheap and comparing short strings is too
370 * should be faster than getting the quark for name and comparing the quarks
371 */
372 structure_name = g_quark_to_string (structure->name);
374 return (structure_name && strcmp (structure_name, name) == 0);
375 }
377 /**
378 * gst_structure_get_name_id:
379 * @structure: a #GstStructure
380 *
381 * Get the name of @structure as a GQuark.
382 *
383 * Returns: the quark representing the name of the structure.
384 */
385 GQuark
386 gst_structure_get_name_id (const GstStructure * structure)
387 {
388 g_return_val_if_fail (structure != NULL, 0);
390 return structure->name;
391 }
393 /**
394 * gst_structure_set_name:
395 * @structure: a #GstStructure
396 * @name: the new name of the structure
397 *
398 * Sets the name of the structure to the given @name. The string
399 * provided is copied before being used. It must not be empty, start with a
400 * letter and can be followed by letters, numbers and any of "/-_.:".
401 */
402 void
403 gst_structure_set_name (GstStructure * structure, const gchar * name)
404 {
405 g_return_if_fail (structure != NULL);
406 g_return_if_fail (IS_MUTABLE (structure));
407 g_return_if_fail (gst_structure_validate_name (name));
409 structure->name = g_quark_from_string (name);
410 }
412 /**
413 * gst_structure_id_set_value:
414 * @structure: a #GstStructure
415 * @field: a #GQuark representing a field
416 * @value: the new value of the field
417 *
418 * Sets the field with the given GQuark @field to @value. If the field
419 * does not exist, it is created. If the field exists, the previous
420 * value is replaced and freed.
421 */
422 void
423 gst_structure_id_set_value (GstStructure * structure,
424 GQuark field, const GValue * value)
425 {
426 GstStructureField gsfield = { 0, {0,} };
428 g_return_if_fail (structure != NULL);
429 g_return_if_fail (G_IS_VALUE (value));
430 g_return_if_fail (IS_MUTABLE (structure));
432 if (G_VALUE_HOLDS_STRING (value)) {
433 const gchar *s;
435 s = g_value_get_string (value);
436 if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) {
437 g_warning ("Trying to set string field '%s' on structure, but string is "
438 "not valid UTF-8. Please file a bug.", g_quark_to_string (field));
439 return;
440 }
441 }
443 gsfield.name = field;
444 gst_value_init_and_copy (&gsfield.value, value);
446 gst_structure_set_field (structure, &gsfield);
447 }
449 /**
450 * gst_structure_set_value:
451 * @structure: a #GstStructure
452 * @fieldname: the name of the field to set
453 * @value: the new value of the field
454 *
455 * Sets the field with the given name @field to @value. If the field
456 * does not exist, it is created. If the field exists, the previous
457 * value is replaced and freed.
458 */
459 void
460 gst_structure_set_value (GstStructure * structure,
461 const gchar * fieldname, const GValue * value)
462 {
463 g_return_if_fail (structure != NULL);
464 g_return_if_fail (fieldname != NULL);
465 g_return_if_fail (G_IS_VALUE (value));
466 g_return_if_fail (IS_MUTABLE (structure));
468 gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
469 value);
470 }
472 /**
473 * gst_structure_set:
474 * @structure: a #GstStructure
475 * @fieldname: the name of the field to set
476 * @...: variable arguments
477 *
478 * Parses the variable arguments and sets fields accordingly.
479 * Variable arguments should be in the form field name, field type
480 * (as a GType), value(s). The last variable argument should be NULL.
481 */
482 void
483 gst_structure_set (GstStructure * structure, const gchar * field, ...)
484 {
485 va_list varargs;
487 g_return_if_fail (structure != NULL);
489 va_start (varargs, field);
491 gst_structure_set_valist (structure, field, varargs);
493 va_end (varargs);
494 }
496 /**
497 * gst_structure_set_valist:
498 * @structure: a #GstStructure
499 * @fieldname: the name of the field to set
500 * @varargs: variable arguments
501 *
502 * va_list form of gst_structure_set().
503 */
504 void
505 gst_structure_set_valist (GstStructure * structure,
506 const gchar * fieldname, va_list varargs)
507 {
508 gchar *err = NULL;
509 GType type;
511 g_return_if_fail (structure != NULL);
512 g_return_if_fail (IS_MUTABLE (structure));
514 while (fieldname) {
515 GstStructureField field = { 0 };
517 field.name = g_quark_from_string (fieldname);
519 type = va_arg (varargs, GType);
521 if (type == G_TYPE_DATE) {
522 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
523 type = GST_TYPE_DATE;
524 }
526 g_value_init (&field.value, type);
527 G_VALUE_COLLECT (&field.value, varargs, 0, &err);
528 if (err) {
529 g_critical ("%s", err);
530 return;
531 }
532 gst_structure_set_field (structure, &field);
534 fieldname = va_arg (varargs, gchar *);
535 }
536 }
538 /**
539 * gst_structure_id_set:
540 * @structure: a #GstStructure
541 * @fieldname: the GQuark for the name of the field to set
542 * @...: variable arguments
543 *
544 * Identical to gst_structure_set, except that field names are
545 * passed using the GQuark for the field name. This allows more efficient
546 * setting of the structure if the caller already knows the associated
547 * quark values.
548 * The last variable argument must be NULL.
549 *
550 * Since: 0.10.10
551 */
552 void
553 gst_structure_id_set (GstStructure * structure, GQuark field, ...)
554 {
555 va_list varargs;
557 g_return_if_fail (structure != NULL);
559 va_start (varargs, field);
560 gst_structure_id_set_valist (structure, field, varargs);
561 va_end (varargs);
562 }
564 /**
565 * gst_structure_id_set_valist:
566 * @structure: a #GstStructure
567 * @fieldname: the name of the field to set
568 * @varargs: variable arguments
569 *
570 * va_list form of gst_structure_id_set().
571 *
572 * Since: 0.10.10
573 */
574 void
575 gst_structure_id_set_valist (GstStructure * structure,
576 GQuark fieldname, va_list varargs)
577 {
578 gchar *err = NULL;
579 GType type;
581 g_return_if_fail (structure != NULL);
582 g_return_if_fail (IS_MUTABLE (structure));
584 while (fieldname) {
585 GstStructureField field = { 0 };
587 field.name = fieldname;
589 type = va_arg (varargs, GType);
591 if (type == G_TYPE_DATE) {
592 g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
593 type = GST_TYPE_DATE;
594 }
596 g_value_init (&field.value, type);
597 G_VALUE_COLLECT (&field.value, varargs, 0, &err);
598 if (err) {
599 g_critical ("%s", err);
600 return;
601 }
602 gst_structure_set_field (structure, &field);
604 fieldname = va_arg (varargs, GQuark);
605 }
606 }
608 /* If the structure currently contains a field with the same name, it is
609 * replaced with the provided field. Otherwise, the field is added to the
610 * structure. The field's value is not deeply copied.
611 */
612 static void
613 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
614 {
615 GstStructureField *f;
616 guint i;
618 for (i = 0; i < structure->fields->len; i++) {
619 f = GST_STRUCTURE_FIELD (structure, i);
621 if (f->name == field->name) {
622 g_value_unset (&f->value);
623 memcpy (f, field, sizeof (GstStructureField));
624 return;
625 }
626 }
628 g_array_append_val (structure->fields, *field);
629 }
631 /* If there is no field with the given ID, NULL is returned.
632 */
633 static GstStructureField *
634 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
635 {
636 GstStructureField *field;
637 guint i;
639 g_return_val_if_fail (structure != NULL, NULL);
641 for (i = 0; i < structure->fields->len; i++) {
642 field = GST_STRUCTURE_FIELD (structure, i);
644 if (field->name == field_id)
645 return field;
646 }
648 return NULL;
649 }
651 /* If there is no field with the given ID, NULL is returned.
652 */
653 static GstStructureField *
654 gst_structure_get_field (const GstStructure * structure,
655 const gchar * fieldname)
656 {
657 g_return_val_if_fail (structure != NULL, NULL);
658 g_return_val_if_fail (fieldname != NULL, NULL);
660 return gst_structure_id_get_field (structure,
661 g_quark_from_string (fieldname));
662 }
664 /**
665 * gst_structure_get_value:
666 * @structure: a #GstStructure
667 * @fieldname: the name of the field to get
668 *
669 * Get the value of the field with name @fieldname.
670 *
671 * Returns: the #GValue corresponding to the field with the given name.
672 */
673 const GValue *
674 gst_structure_get_value (const GstStructure * structure,
675 const gchar * fieldname)
676 {
677 GstStructureField *field;
679 g_return_val_if_fail (structure != NULL, NULL);
680 g_return_val_if_fail (fieldname != NULL, NULL);
682 field = gst_structure_get_field (structure, fieldname);
683 if (field == NULL)
684 return NULL;
686 return &field->value;
687 }
689 /**
690 * gst_structure_id_get_value:
691 * @structure: a #GstStructure
692 * @field: the #GQuark of the field to get
693 *
694 * Get the value of the field with GQuark @field.
695 *
696 * Returns: the #GValue corresponding to the field with the given name
697 * identifier.
698 */
699 const GValue *
700 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
701 {
702 GstStructureField *gsfield;
704 g_return_val_if_fail (structure != NULL, NULL);
706 gsfield = gst_structure_id_get_field (structure, field);
707 if (gsfield == NULL)
708 return NULL;
710 return &gsfield->value;
711 }
713 /**
714 * gst_structure_remove_field:
715 * @structure: a #GstStructure
716 * @fieldname: the name of the field to remove
717 *
718 * Removes the field with the given name. If the field with the given
719 * name does not exist, the structure is unchanged.
720 */
721 void
722 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
723 {
724 GstStructureField *field;
725 GQuark id;
726 guint i;
728 g_return_if_fail (structure != NULL);
729 g_return_if_fail (fieldname != NULL);
730 g_return_if_fail (IS_MUTABLE (structure));
732 id = g_quark_from_string (fieldname);
734 for (i = 0; i < structure->fields->len; i++) {
735 field = GST_STRUCTURE_FIELD (structure, i);
737 if (field->name == id) {
738 if (G_IS_VALUE (&field->value)) {
739 g_value_unset (&field->value);
740 }
741 structure->fields = g_array_remove_index (structure->fields, i);
742 return;
743 }
744 }
745 }
747 /**
748 * gst_structure_remove_fields:
749 * @structure: a #GstStructure
750 * @fieldname: the name of the field to remove
751 * @...: NULL-terminated list of more fieldnames to remove
752 *
753 * Removes the fields with the given names. If a field does not exist, the
754 * argument is ignored.
755 */
756 void
757 gst_structure_remove_fields (GstStructure * structure,
758 const gchar * fieldname, ...)
759 {
760 va_list varargs;
762 g_return_if_fail (structure != NULL);
763 g_return_if_fail (fieldname != NULL);
764 /* mutability checked in remove_field */
766 va_start (varargs, fieldname);
768 gst_structure_remove_fields_valist (structure, fieldname, varargs);
770 va_end (varargs);
771 }
773 /**
774 * gst_structure_remove_fields_valist:
775 * @structure: a #GstStructure
776 * @fieldname: the name of the field to remove
777 * @varargs: NULL-terminated list of more fieldnames to remove
778 *
779 * va_list form of gst_structure_remove_fields().
780 */
781 void
782 gst_structure_remove_fields_valist (GstStructure * structure,
783 const gchar * fieldname, va_list varargs)
784 {
785 gchar *field = (gchar *) fieldname;
787 g_return_if_fail (structure != NULL);
788 g_return_if_fail (fieldname != NULL);
789 /* mutability checked in remove_field */
791 while (field) {
792 gst_structure_remove_field (structure, field);
793 field = va_arg (varargs, char *);
794 }
795 }
797 /**
798 * gst_structure_remove_all_fields:
799 * @structure: a #GstStructure
800 *
801 * Removes all fields in a GstStructure.
802 */
803 void
804 gst_structure_remove_all_fields (GstStructure * structure)
805 {
806 GstStructureField *field;
807 int i;
809 g_return_if_fail (structure != NULL);
810 g_return_if_fail (IS_MUTABLE (structure));
812 for (i = structure->fields->len - 1; i >= 0; i--) {
813 field = GST_STRUCTURE_FIELD (structure, i);
815 if (G_IS_VALUE (&field->value)) {
816 g_value_unset (&field->value);
817 }
818 structure->fields = g_array_remove_index (structure->fields, i);
819 }
820 }
822 /**
823 * gst_structure_get_field_type:
824 * @structure: a #GstStructure
825 * @fieldname: the name of the field
826 *
827 * Finds the field with the given name, and returns the type of the
828 * value it contains. If the field is not found, G_TYPE_INVALID is
829 * returned.
830 *
831 * Returns: the #GValue of the field
832 */
833 GType
834 gst_structure_get_field_type (const GstStructure * structure,
835 const gchar * fieldname)
836 {
837 GstStructureField *field;
839 g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
840 g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
842 field = gst_structure_get_field (structure, fieldname);
843 if (field == NULL)
844 return G_TYPE_INVALID;
846 return G_VALUE_TYPE (&field->value);
847 }
849 /**
850 * gst_structure_n_fields:
851 * @structure: a #GstStructure
852 *
853 * Get the number of fields in the structure.
854 *
855 * Returns: the number of fields in the structure
856 */
857 gint
858 gst_structure_n_fields (const GstStructure * structure)
859 {
860 g_return_val_if_fail (structure != NULL, 0);
862 return structure->fields->len;
863 }
865 /**
866 * gst_structure_nth_field_name:
867 * @structure: a #GstStructure
868 * @index: the index to get the name of
869 *
870 * Get the name of the given field number, counting from 0 onwards.
871 *
872 * Returns: the name of the given field number
873 */
874 const gchar *
875 gst_structure_nth_field_name (const GstStructure * structure, guint index)
876 {
877 GstStructureField *field;
879 g_return_val_if_fail (structure != NULL, NULL);
880 g_return_val_if_fail (index < structure->fields->len, NULL);
882 field = GST_STRUCTURE_FIELD (structure, index);
884 return g_quark_to_string (field->name);
885 }
887 /**
888 * gst_structure_foreach:
889 * @structure: a #GstStructure
890 * @func: a function to call for each field
891 * @user_data: private data
892 *
893 * Calls the provided function once for each field in the #GstStructure. The
894 * function must not modify the fields. Also see gst_structure_map_in_place().
895 *
896 * Returns: TRUE if the supplied function returns TRUE For each of the fields,
897 * FALSE otherwise.
898 */
899 gboolean
900 gst_structure_foreach (const GstStructure * structure,
901 GstStructureForeachFunc func, gpointer user_data)
902 {
903 guint i;
904 GstStructureField *field;
905 gboolean ret;
907 g_return_val_if_fail (structure != NULL, FALSE);
908 g_return_val_if_fail (func != NULL, FALSE);
910 for (i = 0; i < structure->fields->len; i++) {
911 field = GST_STRUCTURE_FIELD (structure, i);
913 ret = func (field->name, &field->value, user_data);
914 if (!ret)
915 return FALSE;
916 }
918 return TRUE;
919 }
921 /**
922 * gst_structure_map_in_place:
923 * @structure: a #GstStructure
924 * @func: a function to call for each field
925 * @user_data: private data
926 *
927 * Calls the provided function once for each field in the #GstStructure. In
928 * contrast to gst_structure_foreach(), the function may modify but not delete the
929 * fields. The structure must be mutable.
930 *
931 * Returns: TRUE if the supplied function returns TRUE For each of the fields,
932 * FALSE otherwise.
933 */
934 gboolean
935 gst_structure_map_in_place (GstStructure * structure,
936 GstStructureMapFunc func, gpointer user_data)
937 {
938 guint i;
939 GstStructureField *field;
940 gboolean ret;
942 g_return_val_if_fail (structure != NULL, FALSE);
943 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
944 g_return_val_if_fail (func != NULL, FALSE);
946 for (i = 0; i < structure->fields->len; i++) {
947 field = GST_STRUCTURE_FIELD (structure, i);
949 ret = func (field->name, &field->value, user_data);
950 if (!ret)
951 return FALSE;
952 }
954 return TRUE;
955 }
957 /**
958 * gst_structure_has_field:
959 * @structure: a #GstStructure
960 * @fieldname: the name of a field
961 *
962 * Check if @structure contains a field named @fieldname.
963 *
964 * Returns: TRUE if the structure contains a field with the given name
965 */
966 gboolean
967 gst_structure_has_field (const GstStructure * structure,
968 const gchar * fieldname)
969 {
970 GstStructureField *field;
972 g_return_val_if_fail (structure != NULL, 0);
973 g_return_val_if_fail (fieldname != NULL, 0);
975 field = gst_structure_get_field (structure, fieldname);
977 return (field != NULL);
978 }
980 /**
981 * gst_structure_has_field_typed:
982 * @structure: a #GstStructure
983 * @fieldname: the name of a field
984 * @type: the type of a value
985 *
986 * Check if @structure contains a field named @fieldname and with GType @type.
987 *
988 * Returns: TRUE if the structure contains a field with the given name and type
989 */
990 gboolean
991 gst_structure_has_field_typed (const GstStructure * structure,
992 const gchar * fieldname, GType type)
993 {
994 GstStructureField *field;
996 g_return_val_if_fail (structure != NULL, 0);
997 g_return_val_if_fail (fieldname != NULL, 0);
999 field = gst_structure_get_field (structure, fieldname);
1000 if (field == NULL)
1001 return FALSE;
1003 return (G_VALUE_TYPE (&field->value) == type);
1004 }
1007 /* utility functions */
1009 /**
1010 * gst_structure_get_boolean:
1011 * @structure: a #GstStructure
1012 * @fieldname: the name of a field
1013 * @value: a pointer to a #gboolean to set
1014 *
1015 * Sets the boolean pointed to by @value corresponding to the value of the
1016 * given field. Caller is responsible for making sure the field exists
1017 * and has the correct type.
1018 *
1019 * Returns: TRUE if the value could be set correctly. If there was no field
1020 * with @fieldname or the existing field did not contain a boolean, this
1021 * function returns FALSE.
1022 */
1023 gboolean
1024 gst_structure_get_boolean (const GstStructure * structure,
1025 const gchar * fieldname, gboolean * value)
1026 {
1027 GstStructureField *field;
1029 g_return_val_if_fail (structure != NULL, FALSE);
1030 g_return_val_if_fail (fieldname != NULL, FALSE);
1032 field = gst_structure_get_field (structure, fieldname);
1034 if (field == NULL)
1035 return FALSE;
1036 if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
1037 return FALSE;
1039 *value = g_value_get_boolean (&field->value);
1041 return TRUE;
1042 }
1044 /**
1045 * gst_structure_get_int:
1046 * @structure: a #GstStructure
1047 * @fieldname: the name of a field
1048 * @value: a pointer to an int to set
1049 *
1050 * Sets the int pointed to by @value corresponding to the value of the
1051 * given field. Caller is responsible for making sure the field exists
1052 * and has the correct type.
1053 *
1054 * Returns: %TRUE if the value could be set correctly. If there was no field
1055 * with @fieldname or the existing field did not contain an int, this function
1056 * returns %FALSE.
1057 */
1058 gboolean
1059 gst_structure_get_int (const GstStructure * structure,
1060 const gchar * fieldname, gint * value)
1061 {
1062 GstStructureField *field;
1064 g_return_val_if_fail (structure != NULL, FALSE);
1065 g_return_val_if_fail (fieldname != NULL, FALSE);
1066 g_return_val_if_fail (value != NULL, FALSE);
1068 field = gst_structure_get_field (structure, fieldname);
1070 if (field == NULL)
1071 return FALSE;
1072 if (!G_VALUE_HOLDS_INT (&field->value))
1073 return FALSE;
1075 *value = g_value_get_int (&field->value);
1077 return TRUE;
1078 }
1080 /**
1081 * gst_structure_get_uint:
1082 * @structure: a #GstStructure
1083 * @fieldname: the name of a field
1084 * @value: a pointer to a uint to set
1085 *
1086 * Sets the uint pointed to by @value corresponding to the value of the
1087 * given field. Caller is responsible for making sure the field exists
1088 * and has the correct type.
1089 *
1090 * Returns: %TRUE if the value could be set correctly. If there was no field
1091 * with @fieldname or the existing field did not contain a uint, this function
1092 * returns %FALSE.
1093 *
1094 * Since: 0.10.15
1095 */
1096 gboolean
1097 gst_structure_get_uint (const GstStructure * structure,
1098 const gchar * fieldname, guint * value)
1099 {
1100 GstStructureField *field;
1102 g_return_val_if_fail (structure != NULL, FALSE);
1103 g_return_val_if_fail (fieldname != NULL, FALSE);
1104 g_return_val_if_fail (value != NULL, FALSE);
1106 field = gst_structure_get_field (structure, fieldname);
1108 if (field == NULL)
1109 return FALSE;
1110 if (!G_VALUE_HOLDS_UINT (&field->value))
1111 return FALSE;
1113 *value = g_value_get_uint (&field->value);
1115 return TRUE;
1116 }
1118 /**
1119 * gst_structure_get_fourcc:
1120 * @structure: a #GstStructure
1121 * @fieldname: the name of a field
1122 * @value: a pointer to a #GstFourcc to set
1123 *
1124 * Sets the #GstFourcc pointed to by @value corresponding to the value of the
1125 * given field. Caller is responsible for making sure the field exists
1126 * and has the correct type.
1127 *
1128 * Returns: TRUE if the value could be set correctly. If there was no field
1129 * with @fieldname or the existing field did not contain a fourcc, this function
1130 * returns FALSE.
1131 */
1132 gboolean
1133 gst_structure_get_fourcc (const GstStructure * structure,
1134 const gchar * fieldname, guint32 * value)
1135 {
1136 GstStructureField *field;
1138 g_return_val_if_fail (structure != NULL, FALSE);
1139 g_return_val_if_fail (fieldname != NULL, FALSE);
1140 g_return_val_if_fail (value != NULL, FALSE);
1142 field = gst_structure_get_field (structure, fieldname);
1144 if (field == NULL)
1145 return FALSE;
1146 if (!GST_VALUE_HOLDS_FOURCC (&field->value))
1147 return FALSE;
1149 *value = gst_value_get_fourcc (&field->value);
1151 return TRUE;
1152 }
1154 /**
1155 * gst_structure_get_date:
1156 * @structure: a #GstStructure
1157 * @fieldname: the name of a field
1158 * @value: a pointer to a #GDate to set
1159 *
1160 * Sets the date pointed to by @value corresponding to the date of the
1161 * given field. Caller is responsible for making sure the field exists
1162 * and has the correct type.
1163 *
1164 * Returns: TRUE if the value could be set correctly. If there was no field
1165 * with @fieldname or the existing field did not contain a data, this function
1166 * returns FALSE.
1167 */
1168 gboolean
1169 gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
1170 GDate ** value)
1171 {
1172 GstStructureField *field;
1174 g_return_val_if_fail (structure != NULL, FALSE);
1175 g_return_val_if_fail (fieldname != NULL, FALSE);
1176 g_return_val_if_fail (value != NULL, FALSE);
1178 field = gst_structure_get_field (structure, fieldname);
1180 if (field == NULL)
1181 return FALSE;
1182 if (!GST_VALUE_HOLDS_DATE (&field->value))
1183 return FALSE;
1185 *value = g_value_dup_boxed (&field->value);
1187 return TRUE;
1188 }
1190 /**
1191 * gst_structure_get_clock_time:
1192 * @structure: a #GstStructure
1193 * @fieldname: the name of a field
1194 * @value: a pointer to a #GstClockTime to set
1195 *
1196 * Sets the clock time pointed to by @value corresponding to the clock time
1197 * of the given field. Caller is responsible for making sure the field exists
1198 * and has the correct type.
1199 *
1200 * Returns: TRUE if the value could be set correctly. If there was no field
1201 * with @fieldname or the existing field did not contain a #GstClockTime, this
1202 * function returns FALSE.
1203 */
1204 gboolean
1205 gst_structure_get_clock_time (const GstStructure * structure,
1206 const gchar * fieldname, GstClockTime * value)
1207 {
1208 GstStructureField *field;
1210 g_return_val_if_fail (structure != NULL, FALSE);
1211 g_return_val_if_fail (fieldname != NULL, FALSE);
1212 g_return_val_if_fail (value != NULL, FALSE);
1214 field = gst_structure_get_field (structure, fieldname);
1216 if (field == NULL)
1217 return FALSE;
1218 if (!G_VALUE_HOLDS_UINT64 (&field->value))
1219 return FALSE;
1221 *value = g_value_get_uint64 (&field->value);
1223 return TRUE;
1224 }
1226 /**
1227 * gst_structure_get_double:
1228 * @structure: a #GstStructure
1229 * @fieldname: the name of a field
1230 * @value: a pointer to a #GstFourcc to set
1231 *
1232 * Sets the double pointed to by @value corresponding to the value of the
1233 * given field. Caller is responsible for making sure the field exists
1234 * and has the correct type.
1235 *
1236 * Returns: TRUE if the value could be set correctly. If there was no field
1237 * with @fieldname or the existing field did not contain a double, this
1238 * function returns FALSE.
1239 */
1240 gboolean
1241 gst_structure_get_double (const GstStructure * structure,
1242 const gchar * fieldname, gdouble * value)
1243 {
1244 GstStructureField *field;
1246 g_return_val_if_fail (structure != NULL, FALSE);
1247 g_return_val_if_fail (fieldname != NULL, FALSE);
1248 g_return_val_if_fail (value != NULL, FALSE);
1250 field = gst_structure_get_field (structure, fieldname);
1252 if (field == NULL)
1253 return FALSE;
1254 if (!G_VALUE_HOLDS_DOUBLE (&field->value))
1255 return FALSE;
1257 *value = g_value_get_double (&field->value);
1259 return TRUE;
1260 }
1262 /**
1263 * gst_structure_get_string:
1264 * @structure: a #GstStructure
1265 * @fieldname: the name of a field
1266 *
1267 * Finds the field corresponding to @fieldname, and returns the string
1268 * contained in the field's value. Caller is responsible for making
1269 * sure the field exists and has the correct type.
1270 *
1271 * The string should not be modified, and remains valid until the next
1272 * call to a gst_structure_*() function with the given structure.
1273 *
1274 * Returns: a pointer to the string or NULL when the field did not exist
1275 * or did not contain a string.
1276 */
1277 const gchar *
1278 gst_structure_get_string (const GstStructure * structure,
1279 const gchar * fieldname)
1280 {
1281 GstStructureField *field;
1283 g_return_val_if_fail (structure != NULL, NULL);
1284 g_return_val_if_fail (fieldname != NULL, NULL);
1286 field = gst_structure_get_field (structure, fieldname);
1288 if (field == NULL)
1289 return NULL;
1290 if (!G_VALUE_HOLDS_STRING (&field->value))
1291 return NULL;
1293 return g_value_get_string (&field->value);
1294 }
1296 /**
1297 * gst_structure_get_enum:
1298 * @structure: a #GstStructure
1299 * @fieldname: the name of a field
1300 * @enumtype: the enum type of a field
1301 * @value: a pointer to an int to set
1302 *
1303 * Sets the int pointed to by @value corresponding to the value of the
1304 * given field. Caller is responsible for making sure the field exists,
1305 * has the correct type and that the enumtype is correct.
1306 *
1307 * Returns: TRUE if the value could be set correctly. If there was no field
1308 * with @fieldname or the existing field did not contain an enum of the given
1309 * type, this function returns FALSE.
1310 */
1311 gboolean
1312 gst_structure_get_enum (const GstStructure * structure,
1313 const gchar * fieldname, GType enumtype, gint * value)
1314 {
1315 GstStructureField *field;
1317 g_return_val_if_fail (structure != NULL, FALSE);
1318 g_return_val_if_fail (fieldname != NULL, FALSE);
1319 g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
1320 g_return_val_if_fail (value != NULL, FALSE);
1322 field = gst_structure_get_field (structure, fieldname);
1324 if (field == NULL)
1325 return FALSE;
1326 if (!G_VALUE_HOLDS_ENUM (&field->value))
1327 return FALSE;
1328 if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
1329 return FALSE;
1331 *value = g_value_get_enum (&field->value);
1333 return TRUE;
1334 }
1336 /**
1337 * gst_structure_get_fraction:
1338 * @structure: a #GstStructure
1339 * @fieldname: the name of a field
1340 * @value_numerator: a pointer to an int to set
1341 * @value_denominator: a pointer to an int to set
1342 *
1343 * Sets the integers pointed to by @value_numerator and @value_denominator
1344 * corresponding to the value of the given field. Caller is responsible
1345 * for making sure the field exists and has the correct type.
1346 *
1347 * Returns: TRUE if the values could be set correctly. If there was no field
1348 * with @fieldname or the existing field did not contain a GstFraction, this
1349 * function returns FALSE.
1350 */
1351 gboolean
1352 gst_structure_get_fraction (const GstStructure * structure,
1353 const gchar * fieldname, gint * value_numerator, gint * value_denominator)
1354 {
1355 GstStructureField *field;
1357 g_return_val_if_fail (structure != NULL, FALSE);
1358 g_return_val_if_fail (fieldname != NULL, FALSE);
1359 g_return_val_if_fail (value_numerator != NULL, FALSE);
1360 g_return_val_if_fail (value_denominator != NULL, FALSE);
1362 field = gst_structure_get_field (structure, fieldname);
1364 if (field == NULL)
1365 return FALSE;
1366 if (!GST_VALUE_HOLDS_FRACTION (&field->value))
1367 return FALSE;
1369 *value_numerator = gst_value_get_fraction_numerator (&field->value);
1370 *value_denominator = gst_value_get_fraction_denominator (&field->value);
1372 return TRUE;
1373 }
1375 typedef struct _GstStructureAbbreviation
1376 {
1377 char *type_name;
1378 GType type;
1379 }
1380 GstStructureAbbreviation;
1382 /* return a copy of an array of GstStructureAbbreviation containing all the
1383 * known type_string, GType maps, including abbreviations for common types */
1384 static GstStructureAbbreviation *
1385 gst_structure_get_abbrs (gint * n_abbrs)
1386 {
1387 static GstStructureAbbreviation *abbrs = NULL;
1388 static gint num = 0;
1390 if (abbrs == NULL) {
1391 /* dynamically generate the array */
1392 GstStructureAbbreviation dyn_abbrs[] = {
1393 {"int", G_TYPE_INT}
1394 ,
1395 {"i", G_TYPE_INT}
1396 ,
1397 {"float", G_TYPE_FLOAT}
1398 ,
1399 {"f", G_TYPE_FLOAT}
1400 ,
1401 {"double", G_TYPE_DOUBLE}
1402 ,
1403 {"d", G_TYPE_DOUBLE}
1404 ,
1405 {"buffer", GST_TYPE_BUFFER}
1406 ,
1407 {"fourcc", GST_TYPE_FOURCC}
1408 ,
1409 {"4", GST_TYPE_FOURCC}
1410 ,
1411 {"fraction", GST_TYPE_FRACTION}
1412 ,
1413 {"boolean", G_TYPE_BOOLEAN}
1414 ,
1415 {"bool", G_TYPE_BOOLEAN}
1416 ,
1417 {"b", G_TYPE_BOOLEAN}
1418 ,
1419 {"string", G_TYPE_STRING}
1420 ,
1421 {"str", G_TYPE_STRING}
1422 ,
1423 {"s", G_TYPE_STRING}
1424 ,
1425 {"structure", GST_TYPE_STRUCTURE}
1426 };
1427 num = G_N_ELEMENTS (dyn_abbrs);
1428 /* permanently allocate and copy the array now */
1429 abbrs = g_new0 (GstStructureAbbreviation, num);
1430 memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num);
1431 }
1432 *n_abbrs = num;
1434 return abbrs;
1435 }
1437 /* given a type_name that could be a type abbreviation or a registered GType,
1438 * return a matching GType */
1439 static GType
1440 gst_structure_gtype_from_abbr (const char *type_name)
1441 {
1442 int i;
1443 GstStructureAbbreviation *abbrs;
1444 gint n_abbrs;
1446 g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1448 abbrs = gst_structure_get_abbrs (&n_abbrs);
1450 for (i = 0; i < n_abbrs; i++) {
1451 if (strcmp (type_name, abbrs[i].type_name) == 0) {
1452 return abbrs[i].type;
1453 }
1454 }
1456 /* this is the fallback */
1457 return g_type_from_name (type_name);
1458 }
1460 static const char *
1461 gst_structure_to_abbr (GType type)
1462 {
1463 int i;
1464 GstStructureAbbreviation *abbrs;
1465 gint n_abbrs;
1467 g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1469 abbrs = gst_structure_get_abbrs (&n_abbrs);
1471 for (i = 0; i < n_abbrs; i++) {
1472 if (type == abbrs[i].type) {
1473 return abbrs[i].type_name;
1474 }
1475 }
1477 return g_type_name (type);
1478 }
1480 static GType
1481 gst_structure_value_get_generic_type (GValue * val)
1482 {
1483 if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1484 || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1485 GArray *array = g_value_peek_pointer (val);
1487 if (array->len > 0) {
1488 GValue *value = &g_array_index (array, GValue, 0);
1490 return gst_structure_value_get_generic_type (value);
1491 } else {
1492 return G_TYPE_INT;
1493 }
1494 } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1495 return G_TYPE_INT;
1496 } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1497 return G_TYPE_DOUBLE;
1498 } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
1499 return GST_TYPE_FRACTION;
1500 }
1501 return G_VALUE_TYPE (val);
1502 }
1504 /* keep in sync with gstvalue.c */
1505 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1506 ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1507 ((c) == '.'))
1509 gboolean
1510 priv_gst_structure_append_to_gstring (const GstStructure * structure,
1511 GString * s)
1512 {
1513 GstStructureField *field;
1514 guint i;
1516 g_return_val_if_fail (s != NULL, FALSE);
1518 g_string_append (s, g_quark_to_string (structure->name));
1519 for (i = 0; i < structure->fields->len; i++) {
1520 char *t;
1521 GType type;
1523 field = GST_STRUCTURE_FIELD (structure, i);
1525 t = gst_value_serialize (&field->value);
1526 type = gst_structure_value_get_generic_type (&field->value);
1528 g_string_append_len (s, ", ", 2);
1529 /* FIXME: do we need to escape fieldnames? */
1530 g_string_append (s, g_quark_to_string (field->name));
1531 g_string_append_len (s, "=(", 2);
1532 g_string_append (s, gst_structure_to_abbr (type));
1533 g_string_append_c (s, ')');
1534 g_string_append (s, GST_STR_NULL (t));
1535 g_free (t);
1536 }
1538 g_string_append_c (s, ';');
1539 return TRUE;
1540 }
1542 /**
1543 * gst_structure_to_string:
1544 * @structure: a #GstStructure
1545 *
1546 * Converts @structure to a human-readable string representation.
1547 *
1548 * Returns: a pointer to string allocated by g_malloc(). g_free() after
1549 * usage.
1550 */
1551 gchar *
1552 gst_structure_to_string (const GstStructure * structure)
1553 {
1554 GString *s;
1556 /* NOTE: This function is potentially called by the debug system,
1557 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1558 * should be careful to avoid recursion. This includes any functions
1559 * called by gst_structure_to_string. In particular, calls should
1560 * not use the GST_PTR_FORMAT extension. */
1562 g_return_val_if_fail (structure != NULL, NULL);
1564 /* we estimate a minimum size based on the number of fields in order to
1565 * avoid unnecessary reallocs within GString */
1566 s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure));
1567 priv_gst_structure_append_to_gstring (structure, s);
1568 return g_string_free (s, FALSE);
1569 }
1571 /*
1572 * r will still point to the string. if end == next, the string will not be
1573 * null-terminated. In all other cases it will be.
1574 * end = pointer to char behind end of string, next = pointer to start of
1575 * unread data.
1576 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1577 */
1578 static gboolean
1579 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1580 {
1581 gchar *w;
1583 if (*s == 0)
1584 return FALSE;
1586 if (*s != '"') {
1587 int ret;
1589 ret = gst_structure_parse_simple_string (s, end);
1590 *next = *end;
1592 return ret;
1593 }
1595 w = s;
1596 s++;
1597 while (*s != '"') {
1598 if (*s == 0)
1599 return FALSE;
1601 if (*s == '\\') {
1602 s++;
1603 }
1605 *w = *s;
1606 w++;
1607 s++;
1608 }
1609 s++;
1611 *end = w;
1612 *next = s;
1614 return TRUE;
1615 }
1617 static gboolean
1618 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1619 GType type)
1620 {
1621 GValue value1 = { 0 };
1622 GValue value2 = { 0 };
1623 GType range_type;
1624 gboolean ret;
1626 if (*s != '[')
1627 return FALSE;
1628 s++;
1630 ret = gst_structure_parse_value (s, &s, &value1, type);
1631 if (ret == FALSE)
1632 return FALSE;
1634 while (g_ascii_isspace (*s))
1635 s++;
1637 if (*s != ',')
1638 return FALSE;
1639 s++;
1641 while (g_ascii_isspace (*s))
1642 s++;
1644 ret = gst_structure_parse_value (s, &s, &value2, type);
1645 if (ret == FALSE)
1646 return FALSE;
1648 while (g_ascii_isspace (*s))
1649 s++;
1651 if (*s != ']')
1652 return FALSE;
1653 s++;
1655 if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1656 return FALSE;
1658 if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1659 range_type = GST_TYPE_DOUBLE_RANGE;
1660 g_value_init (value, range_type);
1661 gst_value_set_double_range (value, g_value_get_double (&value1),
1662 g_value_get_double (&value2));
1663 } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1664 range_type = GST_TYPE_INT_RANGE;
1665 g_value_init (value, range_type);
1666 gst_value_set_int_range (value, g_value_get_int (&value1),
1667 g_value_get_int (&value2));
1668 } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
1669 range_type = GST_TYPE_FRACTION_RANGE;
1670 g_value_init (value, range_type);
1671 gst_value_set_fraction_range (value, &value1, &value2);
1672 } else {
1673 return FALSE;
1674 }
1676 *after = s;
1677 return TRUE;
1678 }
1680 static gboolean
1681 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1682 GType type, GType list_type, char begin, char end)
1683 {
1684 GValue list_value = { 0 };
1685 gboolean ret;
1686 GArray *array;
1688 g_value_init (value, list_type);
1689 array = g_value_peek_pointer (value);
1691 if (*s != begin)
1692 return FALSE;
1693 s++;
1695 while (g_ascii_isspace (*s))
1696 s++;
1697 if (*s == end) {
1698 s++;
1699 *after = s;
1700 return TRUE;
1701 }
1703 ret = gst_structure_parse_value (s, &s, &list_value, type);
1704 if (ret == FALSE)
1705 return FALSE;
1707 g_array_append_val (array, list_value);
1709 while (g_ascii_isspace (*s))
1710 s++;
1712 while (*s != end) {
1713 if (*s != ',')
1714 return FALSE;
1715 s++;
1717 while (g_ascii_isspace (*s))
1718 s++;
1720 memset (&list_value, 0, sizeof (list_value));
1721 ret = gst_structure_parse_value (s, &s, &list_value, type);
1722 if (ret == FALSE)
1723 return FALSE;
1725 g_array_append_val (array, list_value);
1726 while (g_ascii_isspace (*s))
1727 s++;
1728 }
1730 s++;
1732 *after = s;
1733 return TRUE;
1734 }
1736 static gboolean
1737 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1738 {
1739 return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1740 '{', '}');
1741 }
1743 static gboolean
1744 gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
1745 GType type)
1746 {
1747 return gst_structure_parse_any_list (s, after, value, type,
1748 GST_TYPE_ARRAY, '<', '>');
1749 }
1751 static gboolean
1752 gst_structure_parse_simple_string (gchar * str, gchar ** end)
1753 {
1754 char *s = str;
1756 while (GST_ASCII_IS_STRING (*s)) {
1757 s++;
1758 }
1760 *end = s;
1762 return (s != str);
1763 }
1765 static gboolean
1766 gst_structure_parse_field (gchar * str,
1767 gchar ** after, GstStructureField * field)
1768 {
1769 gchar *name;
1770 gchar *name_end;
1771 gchar *s;
1772 gchar c;
1774 s = str;
1776 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
1777 s++;
1778 name = s;
1779 if (!gst_structure_parse_simple_string (s, &name_end))
1780 return FALSE;
1782 s = name_end;
1783 while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
1784 s++;
1786 if (*s != '=')
1787 return FALSE;
1788 s++;
1790 c = *name_end;
1791 *name_end = 0;
1792 field->name = g_quark_from_string (name);
1793 *name_end = c;
1795 if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1796 return FALSE;
1798 *after = s;
1799 return TRUE;
1800 }
1802 static gboolean
1803 gst_structure_parse_value (gchar * str,
1804 gchar ** after, GValue * value, GType default_type)
1805 {
1806 gchar *type_name;
1807 gchar *type_end;
1808 gchar *value_s;
1809 gchar *value_end;
1810 gchar *s;
1811 gchar c;
1812 int ret = 0;
1813 GType type = default_type;
1816 s = str;
1817 while (g_ascii_isspace (*s))
1818 s++;
1820 /* check if there's a (type_name) 'cast' */
1821 type_name = NULL;
1822 if (*s == '(') {
1823 type = G_TYPE_INVALID;
1825 s++;
1826 while (g_ascii_isspace (*s))
1827 s++;
1828 type_name = s;
1829 if (!gst_structure_parse_simple_string (s, &type_end))
1830 return FALSE;
1831 s = type_end;
1832 while (g_ascii_isspace (*s))
1833 s++;
1834 if (*s != ')')
1835 return FALSE;
1836 s++;
1837 while (g_ascii_isspace (*s))
1838 s++;
1840 c = *type_end;
1841 *type_end = 0;
1842 type = gst_structure_gtype_from_abbr (type_name);
1843 *type_end = c;
1845 if (type == G_TYPE_INVALID)
1846 return FALSE;
1847 }
1849 while (g_ascii_isspace (*s))
1850 s++;
1851 if (*s == '[') {
1852 ret = gst_structure_parse_range (s, &s, value, type);
1853 } else if (*s == '{') {
1854 ret = gst_structure_parse_list (s, &s, value, type);
1855 } else if (*s == '<') {
1856 ret = gst_structure_parse_array (s, &s, value, type);
1857 } else {
1858 value_s = s;
1859 if (!gst_structure_parse_string (s, &value_end, &s))
1860 return FALSE;
1862 c = *value_end;
1863 *value_end = 0;
1864 if (type == G_TYPE_INVALID) {
1865 GType try_types[] =
1866 { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
1867 G_TYPE_STRING
1868 };
1869 int i;
1871 for (i = 0; i < G_N_ELEMENTS (try_types); i++) {
1872 g_value_init (value, try_types[i]);
1873 ret = gst_value_deserialize (value, value_s);
1874 if (ret)
1875 break;
1876 g_value_unset (value);
1877 }
1878 } else {
1879 g_value_init (value, type);
1881 ret = gst_value_deserialize (value, value_s);
1882 }
1883 *value_end = c;
1884 }
1886 *after = s;
1888 return ret;
1889 }
1891 /**
1892 * gst_structure_from_string:
1893 * @string: a string representation of a #GstStructure.
1894 * @end: pointer to store the end of the string in.
1895 *
1896 * Creates a #GstStructure from a string representation.
1897 * If end is not NULL, a pointer to the place inside the given string
1898 * where parsing ended will be returned.
1899 *
1900 * Returns: a new #GstStructure or NULL when the string could not
1901 * be parsed. Free with gst_structure_free() after use.
1902 */
1903 GstStructure *
1904 gst_structure_from_string (const gchar * string, gchar ** end)
1905 {
1906 char *name;
1907 char *copy;
1908 char *w;
1909 char *r;
1910 char save;
1911 GstStructure *structure = NULL;
1912 GstStructureField field = { 0 };
1914 g_return_val_if_fail (string != NULL, NULL);
1916 copy = g_strdup (string);
1917 r = copy;
1919 /* skip spaces (FIXME: _isspace treats tabs and newlines as space!) */
1920 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
1921 && g_ascii_isspace (r[1]))))
1922 r++;
1924 name = r;
1925 if (!gst_structure_parse_string (r, &w, &r)) {
1926 GST_WARNING ("Failed to parse structure string");
1927 goto error;
1928 }
1930 save = *w;
1931 *w = 0;
1932 structure = gst_structure_empty_new (name);
1933 *w = save;
1935 if (structure == NULL)
1936 goto error;
1938 do {
1939 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
1940 && g_ascii_isspace (r[1]))))
1941 r++;
1942 if (*r == ';') {
1943 /* end of structure, get the next char and finish */
1944 r++;
1945 break;
1946 }
1947 if (*r == '\0') {
1948 /* accept \0 as end delimiter */
1949 break;
1950 }
1951 if (*r != ',') {
1952 GST_WARNING ("Failed to find delimiter, r=%s", r);
1953 goto error;
1954 }
1955 r++;
1956 while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
1957 && g_ascii_isspace (r[1]))))
1958 r++;
1960 memset (&field, 0, sizeof (field));
1961 if (!gst_structure_parse_field (r, &r, &field))
1962 goto error;
1963 gst_structure_set_field (structure, &field);
1965 } while (TRUE);
1967 if (end)
1968 *end = (char *) string + (r - copy);
1969 else if (*r)
1970 g_warning ("gst_structure_from_string did not consume whole string,"
1971 " but caller did not provide end pointer (\"%s\")", string);
1973 g_free (copy);
1974 return structure;
1976 error:
1977 if (structure)
1978 gst_structure_free (structure);
1979 g_free (copy);
1980 return NULL;
1981 }
1983 static void
1984 gst_structure_transform_to_string (const GValue * src_value,
1985 GValue * dest_value)
1986 {
1987 g_return_if_fail (src_value != NULL);
1988 g_return_if_fail (dest_value != NULL);
1990 dest_value->data[0].v_pointer =
1991 gst_structure_to_string (src_value->data[0].v_pointer);
1992 }
1994 static GstStructure *
1995 gst_structure_copy_conditional (const GstStructure * structure)
1996 {
1997 if (structure)
1998 return gst_structure_copy (structure);
1999 return NULL;
2000 }
2002 /* fixate utility functions */
2004 /**
2005 * gst_structure_fixate_field_nearest_int:
2006 * @structure: a #GstStructure
2007 * @field_name: a field in @structure
2008 * @target: the target value of the fixation
2009 *
2010 * Fixates a #GstStructure by changing the given field to the nearest
2011 * integer to @target that is a subset of the existing field.
2012 *
2013 * Returns: TRUE if the structure could be fixated
2014 */
2015 gboolean
2016 gst_structure_fixate_field_nearest_int (GstStructure * structure,
2017 const char *field_name, int target)
2018 {
2019 const GValue *value;
2021 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2022 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2024 value = gst_structure_get_value (structure, field_name);
2026 if (G_VALUE_TYPE (value) == G_TYPE_INT) {
2027 /* already fixed */
2028 return FALSE;
2029 } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
2030 int x;
2032 x = gst_value_get_int_range_min (value);
2033 if (target < x)
2034 target = x;
2035 x = gst_value_get_int_range_max (value);
2036 if (target > x)
2037 target = x;
2038 gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
2039 return TRUE;
2040 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2041 const GValue *list_value;
2042 int i, n;
2043 int best = 0;
2044 int best_index = -1;
2046 n = gst_value_list_get_size (value);
2047 for (i = 0; i < n; i++) {
2048 list_value = gst_value_list_get_value (value, i);
2049 if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
2050 int x = g_value_get_int (list_value);
2052 if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2053 best_index = i;
2054 best = x;
2055 }
2056 }
2057 }
2058 if (best_index != -1) {
2059 gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
2060 return TRUE;
2061 }
2062 return FALSE;
2063 }
2065 return FALSE;
2066 }
2068 /**
2069 * gst_structure_fixate_field_nearest_double:
2070 * @structure: a #GstStructure
2071 * @field_name: a field in @structure
2072 * @target: the target value of the fixation
2073 *
2074 * Fixates a #GstStructure by changing the given field to the nearest
2075 * double to @target that is a subset of the existing field.
2076 *
2077 * Returns: TRUE if the structure could be fixated
2078 */
2079 gboolean
2080 gst_structure_fixate_field_nearest_double (GstStructure * structure,
2081 const char *field_name, double target)
2082 {
2083 const GValue *value;
2085 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2086 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2088 value = gst_structure_get_value (structure, field_name);
2090 if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
2091 /* already fixed */
2092 return FALSE;
2093 } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
2094 double x;
2096 x = gst_value_get_double_range_min (value);
2097 if (target < x)
2098 target = x;
2099 x = gst_value_get_double_range_max (value);
2100 if (target > x)
2101 target = x;
2102 gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
2103 return TRUE;
2104 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2105 const GValue *list_value;
2106 int i, n;
2107 double best = 0;
2108 int best_index = -1;
2110 n = gst_value_list_get_size (value);
2111 for (i = 0; i < n; i++) {
2112 list_value = gst_value_list_get_value (value, i);
2113 if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
2114 double x = g_value_get_double (list_value);
2116 if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2117 best_index = i;
2118 best = x;
2119 }
2120 }
2121 }
2122 if (best_index != -1) {
2123 gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
2124 return TRUE;
2125 }
2126 return FALSE;
2127 }
2129 return FALSE;
2131 }
2133 /**
2134 * gst_structure_fixate_field_boolean:
2135 * @structure: a #GstStructure
2136 * @field_name: a field in @structure
2137 * @target: the target value of the fixation
2138 *
2139 * Fixates a #GstStructure by changing the given @field_name field to the given
2140 * @target boolean if that field is not fixed yet.
2141 *
2142 * Returns: TRUE if the structure could be fixated
2143 */
2144 gboolean
2145 gst_structure_fixate_field_boolean (GstStructure * structure,
2146 const char *field_name, gboolean target)
2147 {
2148 const GValue *value;
2150 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2151 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2153 value = gst_structure_get_value (structure, field_name);
2155 if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
2156 /* already fixed */
2157 return FALSE;
2158 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2159 const GValue *list_value;
2160 int i, n;
2161 int best = 0;
2162 int best_index = -1;
2164 n = gst_value_list_get_size (value);
2165 for (i = 0; i < n; i++) {
2166 list_value = gst_value_list_get_value (value, i);
2167 if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
2168 gboolean x = g_value_get_boolean (list_value);
2170 if (best_index == -1 || x == target) {
2171 best_index = i;
2172 best = x;
2173 }
2174 }
2175 }
2176 if (best_index != -1) {
2177 gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
2178 return TRUE;
2179 }
2180 return FALSE;
2181 }
2183 return FALSE;
2184 }
2186 /**
2187 * gst_structure_fixate_field_nearest_fraction:
2188 * @structure: a #GstStructure
2189 * @field_name: a field in @structure
2190 * @target_numerator: The numerator of the target value of the fixation
2191 * @target_denominator: The denominator of the target value of the fixation
2192 *
2193 * Fixates a #GstStructure by changing the given field to the nearest
2194 * fraction to @target_numerator/@target_denominator that is a subset
2195 * of the existing field.
2196 *
2197 * Returns: TRUE if the structure could be fixated
2198 */
2199 gboolean
2200 gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
2201 const char *field_name, const gint target_numerator,
2202 const gint target_denominator)
2203 {
2204 const GValue *value;
2206 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2207 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2209 value = gst_structure_get_value (structure, field_name);
2211 if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
2212 /* already fixed */
2213 return FALSE;
2214 } else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
2215 const GValue *x, *new_value;
2216 GValue target = { 0 };
2217 g_value_init (&target, GST_TYPE_FRACTION);
2218 gst_value_set_fraction (&target, target_numerator, target_denominator);
2220 new_value = ⌖
2221 x = gst_value_get_fraction_range_min (value);
2222 if (gst_value_compare (&target, x) == GST_VALUE_LESS_THAN)
2223 new_value = x;
2224 x = gst_value_get_fraction_range_max (value);
2225 if (gst_value_compare (&target, x) == GST_VALUE_GREATER_THAN)
2226 new_value = x;
2228 gst_structure_set_value (structure, field_name, new_value);
2229 g_value_unset (&target);
2230 return TRUE;
2231 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2232 const GValue *list_value;
2233 int i, n;
2234 const GValue *best = NULL;
2235 GValue best_diff = { 0 };
2236 GValue cur_diff = { 0 };
2237 GValue target = { 0 };
2238 gboolean res = FALSE;
2240 g_value_init (&best_diff, GST_TYPE_FRACTION);
2241 g_value_init (&cur_diff, GST_TYPE_FRACTION);
2242 g_value_init (&target, GST_TYPE_FRACTION);
2244 gst_value_set_fraction (&target, target_numerator, target_denominator);
2246 best = NULL;
2248 n = gst_value_list_get_size (value);
2249 for (i = 0; i < n; i++) {
2250 list_value = gst_value_list_get_value (value, i);
2251 if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
2253 if (gst_value_compare (list_value, &target) == GST_VALUE_LESS_THAN)
2254 gst_value_fraction_subtract (&cur_diff, &target, list_value);
2255 else
2256 gst_value_fraction_subtract (&cur_diff, list_value, &target);
2258 if (!best
2259 || gst_value_compare (&cur_diff,
2260 &best_diff) == GST_VALUE_LESS_THAN) {
2261 best = list_value;
2262 g_value_copy (&cur_diff, &best_diff);
2263 }
2264 }
2265 }
2266 if (best != NULL) {
2267 gst_structure_set_value (structure, field_name, best);
2268 res = TRUE;
2269 }
2270 g_value_unset (&best_diff);
2271 g_value_unset (&cur_diff);
2272 g_value_unset (&target);
2273 return res;
2274 }
2275 return FALSE;
2276 }