]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - gst/gststructure.c
docs: fix Since: markers for API added after 0.10.35
[glsdk/gstreamer0-10.git] / gst / gststructure.c
1 /* GStreamer
2  * Copyright (C) 2003 David A. Schleef <ds@schleef.org>
3  *
4  * gststructure.c: lists of { GQuark, GValue } tuples
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
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  * 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)
56  */
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
62 #include <string.h>
64 #include "gst_private.h"
65 #include "gstquark.h"
66 #include <gst/gst.h>
67 #include <gobject/gvaluecollector.h>
69 typedef struct _GstStructureField GstStructureField;
71 struct _GstStructureField
72 {
73   GQuark name;
74   GValue value;
75 };
77 #define GST_STRUCTURE_FIELD(structure, index) \
78     &g_array_index((structure)->fields, GstStructureField, (index))
80 #define IS_MUTABLE(structure) \
81     (!(structure)->parent_refcount || \
82      g_atomic_int_get ((structure)->parent_refcount) == 1)
84 #define IS_TAGLIST(structure) \
85     (structure->name == GST_QUARK (TAGLIST))
87 static void gst_structure_set_field (GstStructure * structure,
88     GstStructureField * field);
89 static GstStructureField *gst_structure_get_field (const GstStructure *
90     structure, const gchar * fieldname);
91 static GstStructureField *gst_structure_id_get_field (const GstStructure *
92     structure, GQuark field);
93 static void gst_structure_transform_to_string (const GValue * src_value,
94     GValue * dest_value);
95 static GstStructure *gst_structure_copy_conditional (const GstStructure *
96     structure);
97 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
98     GValue * value, GType default_type);
99 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
101 GType
102 gst_structure_get_type (void)
104   static GType gst_structure_type = 0;
106   if (G_UNLIKELY (gst_structure_type == 0)) {
107     gst_structure_type = g_boxed_type_register_static ("GstStructure",
108         (GBoxedCopyFunc) gst_structure_copy_conditional,
109         (GBoxedFreeFunc) gst_structure_free);
111     g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
112         gst_structure_transform_to_string);
113   }
115   return gst_structure_type;
118 static GstStructure *
119 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
121   GstStructure *structure;
123   structure = g_slice_new (GstStructure);
124   structure->type = gst_structure_get_type ();
125   structure->name = quark;
126   structure->parent_refcount = NULL;
127   structure->fields =
128       g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc);
130   return structure;
133 /**
134  * gst_structure_id_empty_new:
135  * @quark: name of new structure
136  *
137  * Creates a new, empty #GstStructure with the given name as a GQuark.
138  *
139  * Free-function: gst_structure_free
140  *
141  * Returns: (transfer full): a new, empty #GstStructure
142  */
143 GstStructure *
144 gst_structure_id_empty_new (GQuark quark)
146   g_return_val_if_fail (quark != 0, NULL);
148   return gst_structure_id_empty_new_with_size (quark, 0);
151 #ifndef G_DISABLE_CHECKS
152 static gboolean
153 gst_structure_validate_name (const gchar * name)
155   const gchar *s;
157   g_return_val_if_fail (name != NULL, FALSE);
159   /* FIXME 0.11: use g_ascii_isalpha() */
160   if (G_UNLIKELY (!g_ascii_isalnum (*name))) {
161     GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s",
162         *name, name);
163     return FALSE;
164   }
166   /* FIXME 0.11: don't allow spaces */
167   /* FIXME: test name string more */
168   s = &name[1];
169   while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+ ", *s) != NULL))
170     s++;
171   if (G_UNLIKELY (*s != '\0')) {
172     GST_WARNING ("Invalid character '%c' at offset %" G_GUINTPTR_FORMAT " in"
173         " structure name: %s", *s, ((guintptr) s - (guintptr) name), name);
174     return FALSE;
175   }
177   return TRUE;
179 #endif
181 /**
182  * gst_structure_empty_new:
183  * @name: name of new structure
184  *
185  * Creates a new, empty #GstStructure with the given @name.
186  *
187  * See gst_structure_set_name() for constraints on the @name parameter.
188  *
189  * Free-function: gst_structure_free
190  *
191  * Returns: (transfer full): a new, empty #GstStructure
192  */
193 GstStructure *
194 gst_structure_empty_new (const gchar * name)
196   g_return_val_if_fail (gst_structure_validate_name (name), NULL);
198   return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
201 /**
202  * gst_structure_new:
203  * @name: name of new structure
204  * @firstfield: name of first field to set
205  * @...: additional arguments
206  *
207  * Creates a new #GstStructure with the given name.  Parses the
208  * list of variable arguments and sets fields to the values listed.
209  * Variable arguments should be passed as field name, field type,
210  * and value.  Last variable argument should be NULL.
211  *
212  * Free-function: gst_structure_free
213  *
214  * Returns: (transfer full): a new #GstStructure
215  */
216 GstStructure *
217 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
219   GstStructure *structure;
220   va_list varargs;
222   va_start (varargs, firstfield);
223   structure = gst_structure_new_valist (name, firstfield, varargs);
224   va_end (varargs);
226   return structure;
229 /**
230  * gst_structure_new_valist:
231  * @name: name of new structure
232  * @firstfield: name of first field to set
233  * @varargs: variable argument list
234  *
235  * Creates a new #GstStructure with the given @name.  Structure fields
236  * are set according to the varargs in a manner similar to
237  * gst_structure_new().
238  *
239  * See gst_structure_set_name() for constraints on the @name parameter.
240  *
241  * Free-function: gst_structure_free
242  *
243  * Returns: (transfer full): a new #GstStructure
244  */
245 GstStructure *
246 gst_structure_new_valist (const gchar * name,
247     const gchar * firstfield, va_list varargs)
249   GstStructure *structure;
251   structure = gst_structure_empty_new (name);
253   if (structure)
254     gst_structure_set_valist (structure, firstfield, varargs);
256   return structure;
259 /**
260  * gst_structure_set_parent_refcount:
261  * @structure: a #GstStructure
262  * @refcount: (in): a pointer to the parent's refcount
263  *
264  * Sets the parent_refcount field of #GstStructure. This field is used to
265  * determine whether a structure is mutable or not. This function should only be
266  * called by code implementing parent objects of #GstStructure, as described in
267  * the MT Refcounting section of the design documents.
268  */
269 void
270 gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount)
272   g_return_if_fail (structure != NULL);
274   /* if we have a parent_refcount already, we can only clear
275    * if with a NULL refcount */
276   if (structure->parent_refcount)
277     g_return_if_fail (refcount == NULL);
278   else
279     g_return_if_fail (refcount != NULL);
281   structure->parent_refcount = refcount;
284 /**
285  * gst_structure_copy:
286  * @structure: a #GstStructure to duplicate
287  *
288  * Duplicates a #GstStructure and all its fields and values.
289  *
290  * Free-function: gst_structure_free
291  *
292  * Returns: (transfer none): a new #GstStructure.
293  */
294 GstStructure *
295 gst_structure_copy (const GstStructure * structure)
297   GstStructure *new_structure;
298   GstStructureField *field;
299   guint i, len;
301   g_return_val_if_fail (structure != NULL, NULL);
303   len = structure->fields->len;
304   new_structure = gst_structure_id_empty_new_with_size (structure->name, len);
306   for (i = 0; i < len; i++) {
307     GstStructureField new_field = { 0 };
309     field = GST_STRUCTURE_FIELD (structure, i);
311     new_field.name = field->name;
312     gst_value_init_and_copy (&new_field.value, &field->value);
313     g_array_append_val (new_structure->fields, new_field);
314   }
316   return new_structure;
319 /**
320  * gst_structure_free:
321  * @structure: (in) (transfer full): the #GstStructure to free
322  *
323  * Frees a #GstStructure and all its fields and values. The structure must not
324  * have a parent when this function is called.
325  */
326 void
327 gst_structure_free (GstStructure * structure)
329   GstStructureField *field;
330   guint i, len;
332   g_return_if_fail (structure != NULL);
333   g_return_if_fail (structure->parent_refcount == NULL);
335   len = structure->fields->len;
336   for (i = 0; i < len; i++) {
337     field = GST_STRUCTURE_FIELD (structure, i);
339     if (G_IS_VALUE (&field->value)) {
340       g_value_unset (&field->value);
341     }
342   }
343   g_array_free (structure->fields, TRUE);
344 #ifdef USE_POISONING
345   memset (structure, 0xff, sizeof (GstStructure));
346 #endif
347   g_slice_free (GstStructure, structure);
350 /**
351  * gst_structure_get_name:
352  * @structure: a #GstStructure
353  *
354  * Get the name of @structure as a string.
355  *
356  * Returns: the name of the structure.
357  */
358 const gchar *
359 gst_structure_get_name (const GstStructure * structure)
361   g_return_val_if_fail (structure != NULL, NULL);
363   return g_quark_to_string (structure->name);
366 /**
367  * gst_structure_has_name:
368  * @structure: a #GstStructure
369  * @name: structure name to check for
370  *
371  * Checks if the structure has the given name
372  *
373  * Returns: TRUE if @name matches the name of the structure.
374  */
375 gboolean
376 gst_structure_has_name (const GstStructure * structure, const gchar * name)
378   const gchar *structure_name;
380   g_return_val_if_fail (structure != NULL, FALSE);
381   g_return_val_if_fail (name != NULL, FALSE);
383   /* getting the string is cheap and comparing short strings is too
384    * should be faster than getting the quark for name and comparing the quarks
385    */
386   structure_name = g_quark_to_string (structure->name);
388   return (structure_name && strcmp (structure_name, name) == 0);
391 /**
392  * gst_structure_get_name_id:
393  * @structure: a #GstStructure
394  *
395  * Get the name of @structure as a GQuark.
396  *
397  * Returns: the quark representing the name of the structure.
398  */
399 GQuark
400 gst_structure_get_name_id (const GstStructure * structure)
402   g_return_val_if_fail (structure != NULL, 0);
404   return structure->name;
407 /**
408  * gst_structure_set_name:
409  * @structure: a #GstStructure
410  * @name: the new name of the structure
411  *
412  * Sets the name of the structure to the given @name.  The string
413  * provided is copied before being used. It must not be empty, start with a
414  * letter and can be followed by letters, numbers and any of "/-_.:".
415  */
416 void
417 gst_structure_set_name (GstStructure * structure, const gchar * name)
419   g_return_if_fail (structure != NULL);
420   g_return_if_fail (IS_MUTABLE (structure));
421   g_return_if_fail (gst_structure_validate_name (name));
423   structure->name = g_quark_from_string (name);
426 static inline void
427 gst_structure_id_set_value_internal (GstStructure * structure, GQuark field,
428     const GValue * value)
430   GstStructureField gsfield = { 0, {0,} };
432   gsfield.name = field;
433   gst_value_init_and_copy (&gsfield.value, value);
435   gst_structure_set_field (structure, &gsfield);
438 /**
439  * gst_structure_id_set_value:
440  * @structure: a #GstStructure
441  * @field: a #GQuark representing a field
442  * @value: the new value of the field
443  *
444  * Sets the field with the given GQuark @field to @value.  If the field
445  * does not exist, it is created.  If the field exists, the previous
446  * value is replaced and freed.
447  */
448 void
449 gst_structure_id_set_value (GstStructure * structure,
450     GQuark field, const GValue * value)
453   g_return_if_fail (structure != NULL);
454   g_return_if_fail (G_IS_VALUE (value));
455   g_return_if_fail (IS_MUTABLE (structure));
457   gst_structure_id_set_value_internal (structure, field, value);
460 /**
461  * gst_structure_set_value:
462  * @structure: a #GstStructure
463  * @fieldname: the name of the field to set
464  * @value: the new value of the field
465  *
466  * Sets the field with the given name @field to @value.  If the field
467  * does not exist, it is created.  If the field exists, the previous
468  * value is replaced and freed.
469  */
470 void
471 gst_structure_set_value (GstStructure * structure,
472     const gchar * fieldname, const GValue * value)
474   g_return_if_fail (structure != NULL);
475   g_return_if_fail (fieldname != NULL);
476   g_return_if_fail (G_IS_VALUE (value));
477   g_return_if_fail (IS_MUTABLE (structure));
479   gst_structure_id_set_value_internal (structure,
480       g_quark_from_string (fieldname), value);
483 static inline void
484 gst_structure_id_take_value_internal (GstStructure * structure, GQuark field,
485     GValue * value)
487   GstStructureField gsfield = { 0, {0,} };
489   gsfield.name = field;
490   gsfield.value = *value;
492   gst_structure_set_field (structure, &gsfield);
494   /* we took ownership */
495 #ifdef USE_POISONING
496   memset (value, 0, sizeof (GValue));
497 #else
498   value->g_type = G_TYPE_INVALID;
499 #endif
502 /**
503  * gst_structure_id_take_value:
504  * @structure: a #GstStructure
505  * @field: a #GQuark representing a field
506  * @value: (transfer full): the new value of the field
507  *
508  * Sets the field with the given GQuark @field to @value.  If the field
509  * does not exist, it is created.  If the field exists, the previous
510  * value is replaced and freed.
511  *
512  * Since: 0.10.31
513  */
514 void
515 gst_structure_id_take_value (GstStructure * structure, GQuark field,
516     GValue * value)
518   g_return_if_fail (structure != NULL);
519   g_return_if_fail (G_IS_VALUE (value));
520   g_return_if_fail (IS_MUTABLE (structure));
522   gst_structure_id_take_value_internal (structure, field, value);
525 /**
526  * gst_structure_take_value:
527  * @structure: a #GstStructure
528  * @fieldname: the name of the field to set
529  * @value: (transfer full): the new value of the field
530  *
531  * Sets the field with the given name @field to @value.  If the field
532  * does not exist, it is created.  If the field exists, the previous
533  * value is replaced and freed. The function will take ownership of @value.
534  *
535  * Since: 0.10.31
536  */
537 void
538 gst_structure_take_value (GstStructure * structure, const gchar * fieldname,
539     GValue * value)
541   g_return_if_fail (structure != NULL);
542   g_return_if_fail (fieldname != NULL);
543   g_return_if_fail (G_IS_VALUE (value));
544   g_return_if_fail (IS_MUTABLE (structure));
546   gst_structure_id_take_value_internal (structure,
547       g_quark_from_string (fieldname), value);
550 static void
551 gst_structure_set_valist_internal (GstStructure * structure,
552     const gchar * fieldname, va_list varargs)
554   gchar *err = NULL;
555   GType type;
557   while (fieldname) {
558     GstStructureField field = { 0 };
560     field.name = g_quark_from_string (fieldname);
562     type = va_arg (varargs, GType);
564     if (G_UNLIKELY (type == G_TYPE_DATE)) {
565       g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
566       type = GST_TYPE_DATE;
567     }
568     G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
569     if (G_UNLIKELY (err)) {
570       g_critical ("%s", err);
571       return;
572     }
573     gst_structure_set_field (structure, &field);
575     fieldname = va_arg (varargs, gchar *);
576   }
579 /**
580  * gst_structure_set:
581  * @structure: a #GstStructure
582  * @fieldname: the name of the field to set
583  * @...: variable arguments
584  *
585  * Parses the variable arguments and sets fields accordingly.
586  * Variable arguments should be in the form field name, field type
587  * (as a GType), value(s).  The last variable argument should be NULL.
588  */
589 void
590 gst_structure_set (GstStructure * structure, const gchar * field, ...)
592   va_list varargs;
594   g_return_if_fail (structure != NULL);
595   g_return_if_fail (IS_MUTABLE (structure) || field == NULL);
597   va_start (varargs, field);
598   gst_structure_set_valist_internal (structure, field, varargs);
599   va_end (varargs);
602 /**
603  * gst_structure_set_valist:
604  * @structure: a #GstStructure
605  * @fieldname: the name of the field to set
606  * @varargs: variable arguments
607  *
608  * va_list form of gst_structure_set().
609  */
610 void
611 gst_structure_set_valist (GstStructure * structure,
612     const gchar * fieldname, va_list varargs)
614   g_return_if_fail (structure != NULL);
615   g_return_if_fail (IS_MUTABLE (structure));
617   gst_structure_set_valist_internal (structure, fieldname, varargs);
620 static void
621 gst_structure_id_set_valist_internal (GstStructure * structure,
622     GQuark fieldname, va_list varargs)
624   gchar *err = NULL;
625   GType type;
627   while (fieldname) {
628     GstStructureField field = { 0 };
630     field.name = fieldname;
632     type = va_arg (varargs, GType);
634     if (G_UNLIKELY (type == G_TYPE_DATE)) {
635       g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
636       type = GST_TYPE_DATE;
637     }
638 #ifndef G_VALUE_COLLECT_INIT
639     g_value_init (&field.value, type);
640     G_VALUE_COLLECT (&field.value, varargs, 0, &err);
641 #else
642     G_VALUE_COLLECT_INIT (&field.value, type, varargs, 0, &err);
643 #endif
644     if (G_UNLIKELY (err)) {
645       g_critical ("%s", err);
646       return;
647     }
648     gst_structure_set_field (structure, &field);
650     fieldname = va_arg (varargs, GQuark);
651   }
654 /**
655  * gst_structure_id_set:
656  * @structure: a #GstStructure
657  * @fieldname: the GQuark for the name of the field to set
658  * @...: variable arguments
659  *
660  * Identical to gst_structure_set, except that field names are
661  * passed using the GQuark for the field name. This allows more efficient
662  * setting of the structure if the caller already knows the associated
663  * quark values.
664  * The last variable argument must be NULL.
665  *
666  * Since: 0.10.10
667  */
668 void
669 gst_structure_id_set (GstStructure * structure, GQuark field, ...)
671   va_list varargs;
673   g_return_if_fail (structure != NULL);
675   va_start (varargs, field);
676   gst_structure_id_set_valist_internal (structure, field, varargs);
677   va_end (varargs);
680 /**
681  * gst_structure_id_set_valist:
682  * @structure: a #GstStructure
683  * @fieldname: the name of the field to set
684  * @varargs: variable arguments
685  *
686  * va_list form of gst_structure_id_set().
687  *
688  * Since: 0.10.10
689  */
690 void
691 gst_structure_id_set_valist (GstStructure * structure,
692     GQuark fieldname, va_list varargs)
694   g_return_if_fail (structure != NULL);
695   g_return_if_fail (IS_MUTABLE (structure));
697   gst_structure_id_set_valist_internal (structure, fieldname, varargs);
700 /**
701  * gst_structure_id_new:
702  * @name_quark: name of new structure
703  * @field_quark: the GQuark for the name of the field to set
704  * @...: variable arguments
705  *
706  * Creates a new #GstStructure with the given name as a GQuark, followed by
707  * fieldname quark, GType, argument(s) "triplets" in the same format as
708  * gst_structure_id_set(). Basically a convenience wrapper around
709  * gst_structure_id_empty_new() and gst_structure_id_set().
710  *
711  * The last variable argument must be NULL (or 0).
712  *
713  * Free-function: gst_structure_free
714  *
715  * Returns: (transfer full): a new #GstStructure
716  *
717  * Since: 0.10.24
718  */
719 GstStructure *
720 gst_structure_id_new (GQuark name_quark, GQuark field_quark, ...)
722   GstStructure *s;
723   va_list varargs;
725   g_return_val_if_fail (name_quark != 0, NULL);
726   g_return_val_if_fail (field_quark != 0, NULL);
728   s = gst_structure_id_empty_new (name_quark);
730   va_start (varargs, field_quark);
731   gst_structure_id_set_valist_internal (s, field_quark, varargs);
732   va_end (varargs);
734   return s;
737 #if GST_VERSION_NANO == 1
738 #define GIT_G_WARNING g_warning
739 #else
740 #define GIT_G_WARNING GST_WARNING
741 #endif
743 /* If the structure currently contains a field with the same name, it is
744  * replaced with the provided field. Otherwise, the field is added to the
745  * structure. The field's value is not deeply copied.
746  */
747 static void
748 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
750   GstStructureField *f;
751   guint i, len = structure->fields->len;
753   if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) {
754     const gchar *s;
756     s = g_value_get_string (&field->value);
757     /* only check for NULL strings in taglists, as they are allowed in message
758      * structs, e.g. error message debug strings */
759     if (G_UNLIKELY (IS_TAGLIST (structure) && (s == NULL || *s == '\0'))) {
760       if (s == NULL) {
761         GIT_G_WARNING ("Trying to set NULL string on field '%s' on taglist. "
762             "Please file a bug.", g_quark_to_string (field->name));
763         g_value_unset (&field->value);
764         return;
765       } else {
766         /* empty strings never make sense */
767         GIT_G_WARNING ("Trying to set empty string on taglist field '%s'. "
768             "Please file a bug.", g_quark_to_string (field->name));
769         g_value_unset (&field->value);
770         return;
771       }
772     } else if (G_UNLIKELY (s != NULL && !g_utf8_validate (s, -1, NULL))) {
773       g_warning ("Trying to set string on %s field '%s', but string is not "
774           "valid UTF-8. Please file a bug.",
775           IS_TAGLIST (structure) ? "taglist" : "structure",
776           g_quark_to_string (field->name));
777       g_value_unset (&field->value);
778       return;
779     }
780   } else if (G_UNLIKELY (GST_VALUE_HOLDS_DATE (&field->value))) {
781     const GDate *d;
783     d = gst_value_get_date (&field->value);
784     /* only check for NULL GDates in taglists, as they might make sense
785      * in other, generic structs */
786     if (G_UNLIKELY ((IS_TAGLIST (structure) && d == NULL))) {
787       GIT_G_WARNING ("Trying to set NULL GDate on field '%s' on taglist. "
788           "Please file a bug.", g_quark_to_string (field->name));
789       g_value_unset (&field->value);
790       return;
791     } else if (G_UNLIKELY (d != NULL && !g_date_valid (d))) {
792       g_warning
793           ("Trying to set invalid GDate on %s field '%s'. Please file a bug.",
794           IS_TAGLIST (structure) ? "taglist" : "structure",
795           g_quark_to_string (field->name));
796       g_value_unset (&field->value);
797       return;
798     }
799   }
801   for (i = 0; i < len; i++) {
802     f = GST_STRUCTURE_FIELD (structure, i);
804     if (G_UNLIKELY (f->name == field->name)) {
805       g_value_unset (&f->value);
806       memcpy (f, field, sizeof (GstStructureField));
807       return;
808     }
809   }
811   g_array_append_val (structure->fields, *field);
814 /* If there is no field with the given ID, NULL is returned.
815  */
816 static GstStructureField *
817 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
819   GstStructureField *field;
820   guint i, len;
822   len = structure->fields->len;
824   for (i = 0; i < len; i++) {
825     field = GST_STRUCTURE_FIELD (structure, i);
827     if (G_UNLIKELY (field->name == field_id))
828       return field;
829   }
831   return NULL;
834 /* If there is no field with the given ID, NULL is returned.
835  */
836 static GstStructureField *
837 gst_structure_get_field (const GstStructure * structure,
838     const gchar * fieldname)
840   g_return_val_if_fail (structure != NULL, NULL);
841   g_return_val_if_fail (fieldname != NULL, NULL);
843   return gst_structure_id_get_field (structure,
844       g_quark_from_string (fieldname));
847 /**
848  * gst_structure_get_value:
849  * @structure: a #GstStructure
850  * @fieldname: the name of the field to get
851  *
852  * Get the value of the field with name @fieldname.
853  *
854  * Returns: the #GValue corresponding to the field with the given name.
855  */
856 const GValue *
857 gst_structure_get_value (const GstStructure * structure,
858     const gchar * fieldname)
860   GstStructureField *field;
862   g_return_val_if_fail (structure != NULL, NULL);
863   g_return_val_if_fail (fieldname != NULL, NULL);
865   field = gst_structure_get_field (structure, fieldname);
866   if (field == NULL)
867     return NULL;
869   return &field->value;
872 /**
873  * gst_structure_id_get_value:
874  * @structure: a #GstStructure
875  * @field: the #GQuark of the field to get
876  *
877  * Get the value of the field with GQuark @field.
878  *
879  * Returns: the #GValue corresponding to the field with the given name
880  *          identifier.
881  */
882 const GValue *
883 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
885   GstStructureField *gsfield;
887   g_return_val_if_fail (structure != NULL, NULL);
889   gsfield = gst_structure_id_get_field (structure, field);
890   if (gsfield == NULL)
891     return NULL;
893   return &gsfield->value;
896 /**
897  * gst_structure_remove_field:
898  * @structure: a #GstStructure
899  * @fieldname: the name of the field to remove
900  *
901  * Removes the field with the given name.  If the field with the given
902  * name does not exist, the structure is unchanged.
903  */
904 void
905 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
907   GstStructureField *field;
908   GQuark id;
909   guint i, len;
911   g_return_if_fail (structure != NULL);
912   g_return_if_fail (fieldname != NULL);
913   g_return_if_fail (IS_MUTABLE (structure));
915   id = g_quark_from_string (fieldname);
916   len = structure->fields->len;
918   for (i = 0; i < len; i++) {
919     field = GST_STRUCTURE_FIELD (structure, i);
921     if (field->name == id) {
922       if (G_IS_VALUE (&field->value)) {
923         g_value_unset (&field->value);
924       }
925       structure->fields = g_array_remove_index (structure->fields, i);
926       return;
927     }
928   }
931 /**
932  * gst_structure_remove_fields:
933  * @structure: a #GstStructure
934  * @fieldname: the name of the field to remove
935  * @...: NULL-terminated list of more fieldnames to remove
936  *
937  * Removes the fields with the given names. If a field does not exist, the
938  * argument is ignored.
939  */
940 void
941 gst_structure_remove_fields (GstStructure * structure,
942     const gchar * fieldname, ...)
944   va_list varargs;
946   g_return_if_fail (structure != NULL);
947   g_return_if_fail (fieldname != NULL);
948   /* mutability checked in remove_field */
950   va_start (varargs, fieldname);
951   gst_structure_remove_fields_valist (structure, fieldname, varargs);
952   va_end (varargs);
955 /**
956  * gst_structure_remove_fields_valist:
957  * @structure: a #GstStructure
958  * @fieldname: the name of the field to remove
959  * @varargs: NULL-terminated list of more fieldnames to remove
960  *
961  * va_list form of gst_structure_remove_fields().
962  */
963 void
964 gst_structure_remove_fields_valist (GstStructure * structure,
965     const gchar * fieldname, va_list varargs)
967   gchar *field = (gchar *) fieldname;
969   g_return_if_fail (structure != NULL);
970   g_return_if_fail (fieldname != NULL);
971   /* mutability checked in remove_field */
973   while (field) {
974     gst_structure_remove_field (structure, field);
975     field = va_arg (varargs, char *);
976   }
979 /**
980  * gst_structure_remove_all_fields:
981  * @structure: a #GstStructure
982  *
983  * Removes all fields in a GstStructure.
984  */
985 void
986 gst_structure_remove_all_fields (GstStructure * structure)
988   GstStructureField *field;
989   int i;
991   g_return_if_fail (structure != NULL);
992   g_return_if_fail (IS_MUTABLE (structure));
994   for (i = structure->fields->len - 1; i >= 0; i--) {
995     field = GST_STRUCTURE_FIELD (structure, i);
997     if (G_IS_VALUE (&field->value)) {
998       g_value_unset (&field->value);
999     }
1000     structure->fields = g_array_remove_index (structure->fields, i);
1001   }
1004 /**
1005  * gst_structure_get_field_type:
1006  * @structure: a #GstStructure
1007  * @fieldname: the name of the field
1008  *
1009  * Finds the field with the given name, and returns the type of the
1010  * value it contains.  If the field is not found, G_TYPE_INVALID is
1011  * returned.
1012  *
1013  * Returns: the #GValue of the field
1014  */
1015 GType
1016 gst_structure_get_field_type (const GstStructure * structure,
1017     const gchar * fieldname)
1019   GstStructureField *field;
1021   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
1022   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
1024   field = gst_structure_get_field (structure, fieldname);
1025   if (field == NULL)
1026     return G_TYPE_INVALID;
1028   return G_VALUE_TYPE (&field->value);
1031 /**
1032  * gst_structure_n_fields:
1033  * @structure: a #GstStructure
1034  *
1035  * Get the number of fields in the structure.
1036  *
1037  * Returns: the number of fields in the structure
1038  */
1039 gint
1040 gst_structure_n_fields (const GstStructure * structure)
1042   g_return_val_if_fail (structure != NULL, 0);
1044   return structure->fields->len;
1047 /**
1048  * gst_structure_nth_field_name:
1049  * @structure: a #GstStructure
1050  * @index: the index to get the name of
1051  *
1052  * Get the name of the given field number, counting from 0 onwards.
1053  *
1054  * Returns: the name of the given field number
1055  */
1056 const gchar *
1057 gst_structure_nth_field_name (const GstStructure * structure, guint index)
1059   GstStructureField *field;
1061   g_return_val_if_fail (structure != NULL, NULL);
1062   g_return_val_if_fail (index < structure->fields->len, NULL);
1064   field = GST_STRUCTURE_FIELD (structure, index);
1066   return g_quark_to_string (field->name);
1069 /**
1070  * gst_structure_foreach:
1071  * @structure: a #GstStructure
1072  * @func: (scope call): a function to call for each field
1073  * @user_data: (closure): private data
1074  *
1075  * Calls the provided function once for each field in the #GstStructure. The
1076  * function must not modify the fields. Also see gst_structure_map_in_place().
1077  *
1078  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
1079  * FALSE otherwise.
1080  */
1081 gboolean
1082 gst_structure_foreach (const GstStructure * structure,
1083     GstStructureForeachFunc func, gpointer user_data)
1085   guint i, len;
1086   GstStructureField *field;
1087   gboolean ret;
1089   g_return_val_if_fail (structure != NULL, FALSE);
1090   g_return_val_if_fail (func != NULL, FALSE);
1092   len = structure->fields->len;
1094   for (i = 0; i < len; i++) {
1095     field = GST_STRUCTURE_FIELD (structure, i);
1097     ret = func (field->name, &field->value, user_data);
1098     if (G_UNLIKELY (!ret))
1099       return FALSE;
1100   }
1102   return TRUE;
1105 /**
1106  * gst_structure_map_in_place:
1107  * @structure: a #GstStructure
1108  * @func: (scope call): a function to call for each field
1109  * @user_data: (closure): private data
1110  *
1111  * Calls the provided function once for each field in the #GstStructure. In
1112  * contrast to gst_structure_foreach(), the function may modify but not delete the
1113  * fields. The structure must be mutable.
1114  *
1115  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
1116  * FALSE otherwise.
1117  */
1118 gboolean
1119 gst_structure_map_in_place (GstStructure * structure,
1120     GstStructureMapFunc func, gpointer user_data)
1122   guint i, len;
1123   GstStructureField *field;
1124   gboolean ret;
1126   g_return_val_if_fail (structure != NULL, FALSE);
1127   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1128   g_return_val_if_fail (func != NULL, FALSE);
1129   len = structure->fields->len;
1131   for (i = 0; i < len; i++) {
1132     field = GST_STRUCTURE_FIELD (structure, i);
1134     ret = func (field->name, &field->value, user_data);
1135     if (!ret)
1136       return FALSE;
1137   }
1139   return TRUE;
1142 /**
1143  * gst_structure_id_has_field:
1144  * @structure: a #GstStructure
1145  * @field: #GQuark of the field name
1146  *
1147  * Check if @structure contains a field named @field.
1148  *
1149  * Returns: TRUE if the structure contains a field with the given name
1150  *
1151  * Since: 0.10.26
1152  */
1153 gboolean
1154 gst_structure_id_has_field (const GstStructure * structure, GQuark field)
1156   GstStructureField *f;
1158   g_return_val_if_fail (structure != NULL, FALSE);
1159   g_return_val_if_fail (field != 0, FALSE);
1161   f = gst_structure_id_get_field (structure, field);
1163   return (f != NULL);
1166 /**
1167  * gst_structure_has_field:
1168  * @structure: a #GstStructure
1169  * @fieldname: the name of a field
1170  *
1171  * Check if @structure contains a field named @fieldname.
1172  *
1173  * Returns: TRUE if the structure contains a field with the given name
1174  */
1175 gboolean
1176 gst_structure_has_field (const GstStructure * structure,
1177     const gchar * fieldname)
1179   g_return_val_if_fail (structure != NULL, FALSE);
1180   g_return_val_if_fail (fieldname != NULL, FALSE);
1182   return gst_structure_id_has_field (structure,
1183       g_quark_from_string (fieldname));
1186 /**
1187  * gst_structure_id_has_field_typed:
1188  * @structure: a #GstStructure
1189  * @field: #GQuark of the field name
1190  * @type: the type of a value
1191  *
1192  * Check if @structure contains a field named @field and with GType @type.
1193  *
1194  * Returns: TRUE if the structure contains a field with the given name and type
1195  *
1196  * Since: 0.10.26
1197  */
1198 gboolean
1199 gst_structure_id_has_field_typed (const GstStructure * structure,
1200     GQuark field, GType type)
1202   GstStructureField *f;
1204   g_return_val_if_fail (structure != NULL, FALSE);
1205   g_return_val_if_fail (field != 0, FALSE);
1207   f = gst_structure_id_get_field (structure, field);
1208   if (f == NULL)
1209     return FALSE;
1211   return (G_VALUE_TYPE (&f->value) == type);
1214 /**
1215  * gst_structure_has_field_typed:
1216  * @structure: a #GstStructure
1217  * @fieldname: the name of a field
1218  * @type: the type of a value
1219  *
1220  * Check if @structure contains a field named @fieldname and with GType @type.
1221  *
1222  * Returns: TRUE if the structure contains a field with the given name and type
1223  */
1224 gboolean
1225 gst_structure_has_field_typed (const GstStructure * structure,
1226     const gchar * fieldname, GType type)
1228   g_return_val_if_fail (structure != NULL, FALSE);
1229   g_return_val_if_fail (fieldname != NULL, FALSE);
1231   return gst_structure_id_has_field_typed (structure,
1232       g_quark_from_string (fieldname), type);
1235 /* utility functions */
1237 /**
1238  * gst_structure_get_boolean:
1239  * @structure: a #GstStructure
1240  * @fieldname: the name of a field
1241  * @value: (out): a pointer to a #gboolean to set
1242  *
1243  * Sets the boolean pointed to by @value corresponding to the value of the
1244  * given field.  Caller is responsible for making sure the field exists
1245  * and has the correct type.
1246  *
1247  * Returns: TRUE if the value could be set correctly. If there was no field
1248  * with @fieldname or the existing field did not contain a boolean, this
1249  * function returns FALSE.
1250  */
1251 gboolean
1252 gst_structure_get_boolean (const GstStructure * structure,
1253     const gchar * fieldname, gboolean * value)
1255   GstStructureField *field;
1257   g_return_val_if_fail (structure != NULL, FALSE);
1258   g_return_val_if_fail (fieldname != NULL, FALSE);
1260   field = gst_structure_get_field (structure, fieldname);
1262   if (field == NULL)
1263     return FALSE;
1264   if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
1265     return FALSE;
1267   *value = gst_g_value_get_boolean_unchecked (&field->value);
1269   return TRUE;
1272 /**
1273  * gst_structure_get_int:
1274  * @structure: a #GstStructure
1275  * @fieldname: the name of a field
1276  * @value: (out): a pointer to an int to set
1277  *
1278  * Sets the int pointed to by @value corresponding to the value of the
1279  * given field.  Caller is responsible for making sure the field exists
1280  * and has the correct type.
1281  *
1282  * Returns: %TRUE if the value could be set correctly. If there was no field
1283  * with @fieldname or the existing field did not contain an int, this function
1284  * returns %FALSE.
1285  */
1286 gboolean
1287 gst_structure_get_int (const GstStructure * structure,
1288     const gchar * fieldname, gint * value)
1290   GstStructureField *field;
1292   g_return_val_if_fail (structure != NULL, FALSE);
1293   g_return_val_if_fail (fieldname != NULL, FALSE);
1294   g_return_val_if_fail (value != NULL, FALSE);
1296   field = gst_structure_get_field (structure, fieldname);
1298   if (field == NULL)
1299     return FALSE;
1300   if (!G_VALUE_HOLDS_INT (&field->value))
1301     return FALSE;
1303   *value = gst_g_value_get_int_unchecked (&field->value);
1305   return TRUE;
1308 /**
1309  * gst_structure_get_uint:
1310  * @structure: a #GstStructure
1311  * @fieldname: the name of a field
1312  * @value: (out): a pointer to a uint to set
1313  *
1314  * Sets the uint pointed to by @value corresponding to the value of the
1315  * given field.  Caller is responsible for making sure the field exists
1316  * and has the correct type.
1317  *
1318  * Returns: %TRUE if the value could be set correctly. If there was no field
1319  * with @fieldname or the existing field did not contain a uint, this function
1320  * returns %FALSE.
1321  *
1322  * Since: 0.10.15
1323  */
1324 gboolean
1325 gst_structure_get_uint (const GstStructure * structure,
1326     const gchar * fieldname, guint * value)
1328   GstStructureField *field;
1330   g_return_val_if_fail (structure != NULL, FALSE);
1331   g_return_val_if_fail (fieldname != NULL, FALSE);
1332   g_return_val_if_fail (value != NULL, FALSE);
1334   field = gst_structure_get_field (structure, fieldname);
1336   if (field == NULL)
1337     return FALSE;
1338   if (!G_VALUE_HOLDS_UINT (&field->value))
1339     return FALSE;
1341   *value = gst_g_value_get_uint_unchecked (&field->value);
1343   return TRUE;
1346 /**
1347  * gst_structure_get_fourcc:
1348  * @structure: a #GstStructure
1349  * @fieldname: the name of a field
1350  * @value: (out): a pointer to a 32bit unsigned int to set
1351  *
1352  * Sets the Fourcc pointed to by @value corresponding to the value of the
1353  * given field.  Caller is responsible for making sure the field exists
1354  * and has the correct type.
1355  *
1356  * Returns: TRUE if the value could be set correctly. If there was no field
1357  * with @fieldname or the existing field did not contain a fourcc, this function
1358  * returns FALSE.
1359  */
1360 gboolean
1361 gst_structure_get_fourcc (const GstStructure * structure,
1362     const gchar * fieldname, guint32 * value)
1364   GstStructureField *field;
1366   g_return_val_if_fail (structure != NULL, FALSE);
1367   g_return_val_if_fail (fieldname != NULL, FALSE);
1368   g_return_val_if_fail (value != NULL, FALSE);
1370   field = gst_structure_get_field (structure, fieldname);
1372   if (field == NULL)
1373     return FALSE;
1374   if (!GST_VALUE_HOLDS_FOURCC (&field->value))
1375     return FALSE;
1377   *value = gst_value_get_fourcc (&field->value);
1379   return TRUE;
1382 /**
1383  * gst_structure_get_date:
1384  * @structure: a #GstStructure
1385  * @fieldname: the name of a field
1386  * @value: (out callee-allocates): a pointer to a #GDate to set
1387  *
1388  * Sets the date pointed to by @value corresponding to the date of the
1389  * given field.  Caller is responsible for making sure the field exists
1390  * and has the correct type.
1391  *
1392  * On success @value will point to a newly-allocated copy of the date which
1393  * should be freed with g_date_free() when no longer needed (note: this is
1394  * inconsistent with e.g. gst_structure_get_string() which doesn't return a
1395  * copy of the string).
1396  *
1397  * Returns: TRUE if the value could be set correctly. If there was no field
1398  * with @fieldname or the existing field did not contain a data, this function
1399  * returns FALSE.
1400  */
1401 gboolean
1402 gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
1403     GDate ** value)
1405   GstStructureField *field;
1407   g_return_val_if_fail (structure != NULL, FALSE);
1408   g_return_val_if_fail (fieldname != NULL, FALSE);
1409   g_return_val_if_fail (value != NULL, FALSE);
1411   field = gst_structure_get_field (structure, fieldname);
1413   if (field == NULL)
1414     return FALSE;
1415   if (!GST_VALUE_HOLDS_DATE (&field->value))
1416     return FALSE;
1418   /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */
1419   *value = g_value_dup_boxed (&field->value);
1421   return TRUE;
1424 /**
1425  * gst_structure_get_date_time:
1426  * @structure: a #GstStructure
1427  * @fieldname: the name of a field
1428  * @value: (out callee-allocates): a pointer to a #GstDateTime to set
1429  *
1430  * Sets the datetime pointed to by @value corresponding to the datetime of the
1431  * given field. Caller is responsible for making sure the field exists
1432  * and has the correct type.
1433  *
1434  * On success @value will point to a reference of the datetime which
1435  * should be unreffed with gst_date_time_unref() when no longer needed
1436  * (note: this is inconsistent with e.g. gst_structure_get_string()
1437  * which doesn't return a copy of the string).
1438  *
1439  * Returns: TRUE if the value could be set correctly. If there was no field
1440  * with @fieldname or the existing field did not contain a data, this function
1441  * returns FALSE.
1442  *
1443  * Since: 0.10.31
1444  */
1445 gboolean
1446 gst_structure_get_date_time (const GstStructure * structure,
1447     const gchar * fieldname, GstDateTime ** value)
1449   GstStructureField *field;
1451   g_return_val_if_fail (structure != NULL, FALSE);
1452   g_return_val_if_fail (fieldname != NULL, FALSE);
1453   g_return_val_if_fail (value != NULL, FALSE);
1455   field = gst_structure_get_field (structure, fieldname);
1457   if (field == NULL)
1458     return FALSE;
1459   if (!GST_VALUE_HOLDS_DATE_TIME (&field->value))
1460     return FALSE;
1462   /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */
1463   *value = g_value_dup_boxed (&field->value);
1465   return TRUE;
1468 /**
1469  * gst_structure_get_clock_time:
1470  * @structure: a #GstStructure
1471  * @fieldname: the name of a field
1472  * @value: (out): a pointer to a #GstClockTime to set
1473  *
1474  * Sets the clock time pointed to by @value corresponding to the clock time
1475  * of the given field.  Caller is responsible for making sure the field exists
1476  * and has the correct type.
1477  *
1478  * Returns: TRUE if the value could be set correctly. If there was no field
1479  * with @fieldname or the existing field did not contain a #GstClockTime, this
1480  * function returns FALSE.
1481  */
1482 gboolean
1483 gst_structure_get_clock_time (const GstStructure * structure,
1484     const gchar * fieldname, GstClockTime * value)
1486   GstStructureField *field;
1488   g_return_val_if_fail (structure != NULL, FALSE);
1489   g_return_val_if_fail (fieldname != NULL, FALSE);
1490   g_return_val_if_fail (value != NULL, FALSE);
1492   field = gst_structure_get_field (structure, fieldname);
1494   if (field == NULL)
1495     return FALSE;
1496   if (!G_VALUE_HOLDS_UINT64 (&field->value))
1497     return FALSE;
1499   *value = gst_g_value_get_uint64_unchecked (&field->value);
1501   return TRUE;
1504 /**
1505  * gst_structure_get_double:
1506  * @structure: a #GstStructure
1507  * @fieldname: the name of a field
1508  * @value: (out): a pointer to a gdouble to set
1509  *
1510  * Sets the double pointed to by @value corresponding to the value of the
1511  * given field.  Caller is responsible for making sure the field exists
1512  * and has the correct type.
1513  *
1514  * Returns: TRUE if the value could be set correctly. If there was no field
1515  * with @fieldname or the existing field did not contain a double, this
1516  * function returns FALSE.
1517  */
1518 gboolean
1519 gst_structure_get_double (const GstStructure * structure,
1520     const gchar * fieldname, gdouble * value)
1522   GstStructureField *field;
1524   g_return_val_if_fail (structure != NULL, FALSE);
1525   g_return_val_if_fail (fieldname != NULL, FALSE);
1526   g_return_val_if_fail (value != NULL, FALSE);
1528   field = gst_structure_get_field (structure, fieldname);
1530   if (field == NULL)
1531     return FALSE;
1532   if (!G_VALUE_HOLDS_DOUBLE (&field->value))
1533     return FALSE;
1535   *value = gst_g_value_get_double_unchecked (&field->value);
1537   return TRUE;
1540 /**
1541  * gst_structure_get_string:
1542  * @structure: a #GstStructure
1543  * @fieldname: the name of a field
1544  *
1545  * Finds the field corresponding to @fieldname, and returns the string
1546  * contained in the field's value.  Caller is responsible for making
1547  * sure the field exists and has the correct type.
1548  *
1549  * The string should not be modified, and remains valid until the next
1550  * call to a gst_structure_*() function with the given structure.
1551  *
1552  * Returns: a pointer to the string or NULL when the field did not exist
1553  * or did not contain a string.
1554  */
1555 const gchar *
1556 gst_structure_get_string (const GstStructure * structure,
1557     const gchar * fieldname)
1559   GstStructureField *field;
1561   g_return_val_if_fail (structure != NULL, NULL);
1562   g_return_val_if_fail (fieldname != NULL, NULL);
1564   field = gst_structure_get_field (structure, fieldname);
1566   if (field == NULL)
1567     return NULL;
1568   if (!G_VALUE_HOLDS_STRING (&field->value))
1569     return NULL;
1571   return gst_g_value_get_string_unchecked (&field->value);
1574 /**
1575  * gst_structure_get_enum:
1576  * @structure: a #GstStructure
1577  * @fieldname: the name of a field
1578  * @enumtype: the enum type of a field
1579  * @value: (out): a pointer to an int to set
1580  *
1581  * Sets the int pointed to by @value corresponding to the value of the
1582  * given field.  Caller is responsible for making sure the field exists,
1583  * has the correct type and that the enumtype is correct.
1584  *
1585  * Returns: TRUE if the value could be set correctly. If there was no field
1586  * with @fieldname or the existing field did not contain an enum of the given
1587  * type, this function returns FALSE.
1588  */
1589 gboolean
1590 gst_structure_get_enum (const GstStructure * structure,
1591     const gchar * fieldname, GType enumtype, gint * value)
1593   GstStructureField *field;
1595   g_return_val_if_fail (structure != NULL, FALSE);
1596   g_return_val_if_fail (fieldname != NULL, FALSE);
1597   g_return_val_if_fail (enumtype != G_TYPE_INVALID, FALSE);
1598   g_return_val_if_fail (value != NULL, FALSE);
1600   field = gst_structure_get_field (structure, fieldname);
1602   if (field == NULL)
1603     return FALSE;
1604   if (!G_TYPE_CHECK_VALUE_TYPE (&field->value, enumtype))
1605     return FALSE;
1607   *value = g_value_get_enum (&field->value);
1609   return TRUE;
1612 /**
1613  * gst_structure_get_fraction:
1614  * @structure: a #GstStructure
1615  * @fieldname: the name of a field
1616  * @value_numerator: (out): a pointer to an int to set
1617  * @value_denominator: (out): a pointer to an int to set
1618  *
1619  * Sets the integers pointed to by @value_numerator and @value_denominator
1620  * corresponding to the value of the given field.  Caller is responsible
1621  * for making sure the field exists and has the correct type.
1622  *
1623  * Returns: TRUE if the values could be set correctly. If there was no field
1624  * with @fieldname or the existing field did not contain a GstFraction, this
1625  * function returns FALSE.
1626  */
1627 gboolean
1628 gst_structure_get_fraction (const GstStructure * structure,
1629     const gchar * fieldname, gint * value_numerator, gint * value_denominator)
1631   GstStructureField *field;
1633   g_return_val_if_fail (structure != NULL, FALSE);
1634   g_return_val_if_fail (fieldname != NULL, FALSE);
1635   g_return_val_if_fail (value_numerator != NULL, FALSE);
1636   g_return_val_if_fail (value_denominator != NULL, FALSE);
1638   field = gst_structure_get_field (structure, fieldname);
1640   if (field == NULL)
1641     return FALSE;
1642   if (!GST_VALUE_HOLDS_FRACTION (&field->value))
1643     return FALSE;
1645   *value_numerator = gst_value_get_fraction_numerator (&field->value);
1646   *value_denominator = gst_value_get_fraction_denominator (&field->value);
1648   return TRUE;
1651 typedef struct _GstStructureAbbreviation
1653   const gchar *type_name;
1654   GType type;
1656 GstStructureAbbreviation;
1658 /* return a copy of an array of GstStructureAbbreviation containing all the
1659  * known type_string, GType maps, including abbreviations for common types */
1660 static GstStructureAbbreviation *
1661 gst_structure_get_abbrs (gint * n_abbrs)
1663   static GstStructureAbbreviation *abbrs = NULL;
1664   static volatile gsize num = 0;
1666   if (g_once_init_enter (&num)) {
1667     /* dynamically generate the array */
1668     gsize _num;
1669     GstStructureAbbreviation dyn_abbrs[] = {
1670       {"int", G_TYPE_INT}
1671       ,
1672       {"i", G_TYPE_INT}
1673       ,
1674       {"uint", G_TYPE_UINT}
1675       ,
1676       {"u", G_TYPE_UINT}
1677       ,
1678       {"float", G_TYPE_FLOAT}
1679       ,
1680       {"f", G_TYPE_FLOAT}
1681       ,
1682       {"double", G_TYPE_DOUBLE}
1683       ,
1684       {"d", G_TYPE_DOUBLE}
1685       ,
1686       {"buffer", GST_TYPE_BUFFER}
1687       ,
1688       {"fourcc", GST_TYPE_FOURCC}
1689       ,
1690       {"4", GST_TYPE_FOURCC}
1691       ,
1692       {"fraction", GST_TYPE_FRACTION}
1693       ,
1694       {"boolean", G_TYPE_BOOLEAN}
1695       ,
1696       {"bool", G_TYPE_BOOLEAN}
1697       ,
1698       {"b", G_TYPE_BOOLEAN}
1699       ,
1700       {"string", G_TYPE_STRING}
1701       ,
1702       {"str", G_TYPE_STRING}
1703       ,
1704       {"s", G_TYPE_STRING}
1705       ,
1706       {"structure", GST_TYPE_STRUCTURE}
1707       ,
1708       {"date", GST_TYPE_DATE}
1709       ,
1710       {"datetime", GST_TYPE_DATE_TIME}
1711     };
1712     _num = G_N_ELEMENTS (dyn_abbrs);
1713     /* permanently allocate and copy the array now */
1714     abbrs = g_new0 (GstStructureAbbreviation, _num);
1715     memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * _num);
1716     g_once_init_leave (&num, _num);
1717   }
1718   *n_abbrs = num;
1720   return abbrs;
1723 /* given a type_name that could be a type abbreviation or a registered GType,
1724  * return a matching GType */
1725 static GType
1726 gst_structure_gtype_from_abbr (const char *type_name)
1728   int i;
1729   GstStructureAbbreviation *abbrs;
1730   gint n_abbrs;
1732   g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1734   abbrs = gst_structure_get_abbrs (&n_abbrs);
1736   for (i = 0; i < n_abbrs; i++) {
1737     if (strcmp (type_name, abbrs[i].type_name) == 0) {
1738       return abbrs[i].type;
1739     }
1740   }
1742   /* this is the fallback */
1743   return g_type_from_name (type_name);
1746 static const char *
1747 gst_structure_to_abbr (GType type)
1749   int i;
1750   GstStructureAbbreviation *abbrs;
1751   gint n_abbrs;
1753   g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1755   abbrs = gst_structure_get_abbrs (&n_abbrs);
1757   for (i = 0; i < n_abbrs; i++) {
1758     if (type == abbrs[i].type) {
1759       return abbrs[i].type_name;
1760     }
1761   }
1763   return g_type_name (type);
1766 static GType
1767 gst_structure_value_get_generic_type (GValue * val)
1769   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1770       || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1771     GArray *array = g_value_peek_pointer (val);
1773     if (array->len > 0) {
1774       GValue *value = &g_array_index (array, GValue, 0);
1776       return gst_structure_value_get_generic_type (value);
1777     } else {
1778       return G_TYPE_INT;
1779     }
1780   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1781     return G_TYPE_INT;
1782   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT64_RANGE) {
1783     return G_TYPE_INT64;
1784   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1785     return G_TYPE_DOUBLE;
1786   } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
1787     return GST_TYPE_FRACTION;
1788   }
1789   return G_VALUE_TYPE (val);
1792 gboolean
1793 priv_gst_structure_append_to_gstring (const GstStructure * structure,
1794     GString * s)
1796   GstStructureField *field;
1797   guint i, len;
1799   g_return_val_if_fail (s != NULL, FALSE);
1801   g_string_append (s, g_quark_to_string (structure->name));
1802   len = structure->fields->len;
1803   for (i = 0; i < len; i++) {
1804     char *t;
1805     GType type;
1807     field = GST_STRUCTURE_FIELD (structure, i);
1809     t = gst_value_serialize (&field->value);
1810     type = gst_structure_value_get_generic_type (&field->value);
1812     g_string_append_len (s, ", ", 2);
1813     /* FIXME: do we need to escape fieldnames? */
1814     g_string_append (s, g_quark_to_string (field->name));
1815     g_string_append_len (s, "=(", 2);
1816     g_string_append (s, gst_structure_to_abbr (type));
1817     g_string_append_c (s, ')');
1818     g_string_append (s, t == NULL ? "NULL" : t);
1819     g_free (t);
1820   }
1822   g_string_append_c (s, ';');
1823   return TRUE;
1826 /**
1827  * gst_structure_to_string:
1828  * @structure: a #GstStructure
1829  *
1830  * Converts @structure to a human-readable string representation.
1831  *
1832  * For debugging purposes its easier to do something like this:
1833  * |[
1834  * GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
1835  * ]|
1836  * This prints the structure in human readble form.
1837  *
1838  * Free-function: g_free
1839  *
1840  * Returns: (transfer full)L a pointer to string allocated by g_malloc().
1841  *     g_free() after usage.
1842  */
1843 gchar *
1844 gst_structure_to_string (const GstStructure * structure)
1846   GString *s;
1848   /* NOTE:  This function is potentially called by the debug system,
1849    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1850    * should be careful to avoid recursion.  This includes any functions
1851    * called by gst_structure_to_string.  In particular, calls should
1852    * not use the GST_PTR_FORMAT extension.  */
1854   g_return_val_if_fail (structure != NULL, NULL);
1856   /* we estimate a minimum size based on the number of fields in order to
1857    * avoid unnecessary reallocs within GString */
1858   s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure));
1859   priv_gst_structure_append_to_gstring (structure, s);
1860   return g_string_free (s, FALSE);
1863 /*
1864  * r will still point to the string. if end == next, the string will not be
1865  * null-terminated. In all other cases it will be.
1866  * end = pointer to char behind end of string, next = pointer to start of
1867  * unread data.
1868  * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1869  */
1870 static gboolean
1871 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next,
1872     gboolean unescape)
1874   gchar *w;
1876   if (*s == 0)
1877     return FALSE;
1879   if (*s != '"') {
1880     int ret;
1882     ret = gst_structure_parse_simple_string (s, end);
1883     *next = *end;
1885     return ret;
1886   }
1888   if (unescape) {
1889     w = s;
1890     s++;
1891     while (*s != '"') {
1892       if (G_UNLIKELY (*s == 0))
1893         return FALSE;
1894       if (G_UNLIKELY (*s == '\\'))
1895         s++;
1896       *w = *s;
1897       w++;
1898       s++;
1899     }
1900     s++;
1901   } else {
1902     /* Find the closing quotes */
1903     s++;
1904     while (*s != '"') {
1905       if (G_UNLIKELY (*s == 0))
1906         return FALSE;
1907       if (G_UNLIKELY (*s == '\\'))
1908         s++;
1909       s++;
1910     }
1911     s++;
1912     w = s;
1913   }
1915   *end = w;
1916   *next = s;
1918   return TRUE;
1921 static gboolean
1922 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1923     GType type)
1925   GValue value1 = { 0 };
1926   GValue value2 = { 0 };
1927   GType range_type;
1928   gboolean ret;
1930   if (*s != '[')
1931     return FALSE;
1932   s++;
1934   ret = gst_structure_parse_value (s, &s, &value1, type);
1935   if (ret == FALSE)
1936     return FALSE;
1938   while (g_ascii_isspace (*s))
1939     s++;
1941   if (*s != ',')
1942     return FALSE;
1943   s++;
1945   while (g_ascii_isspace (*s))
1946     s++;
1948   ret = gst_structure_parse_value (s, &s, &value2, type);
1949   if (ret == FALSE)
1950     return FALSE;
1952   while (g_ascii_isspace (*s))
1953     s++;
1955   if (*s != ']')
1956     return FALSE;
1957   s++;
1959   if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1960     return FALSE;
1962   if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1963     range_type = GST_TYPE_DOUBLE_RANGE;
1964     g_value_init (value, range_type);
1965     gst_value_set_double_range (value,
1966         gst_g_value_get_double_unchecked (&value1),
1967         gst_g_value_get_double_unchecked (&value2));
1968   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1969     range_type = GST_TYPE_INT_RANGE;
1970     g_value_init (value, range_type);
1971     gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1),
1972         gst_g_value_get_int_unchecked (&value2));
1973   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
1974     range_type = GST_TYPE_INT64_RANGE;
1975     g_value_init (value, range_type);
1976     gst_value_set_int64_range (value, gst_g_value_get_int64_unchecked (&value1),
1977         gst_g_value_get_int64_unchecked (&value2));
1978   } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
1979     range_type = GST_TYPE_FRACTION_RANGE;
1980     g_value_init (value, range_type);
1981     gst_value_set_fraction_range (value, &value1, &value2);
1982   } else {
1983     return FALSE;
1984   }
1986   *after = s;
1987   return TRUE;
1990 static gboolean
1991 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1992     GType type, GType list_type, char begin, char end)
1994   GValue list_value = { 0 };
1995   gboolean ret;
1996   GArray *array;
1998   g_value_init (value, list_type);
1999   array = g_value_peek_pointer (value);
2001   if (*s != begin)
2002     return FALSE;
2003   s++;
2005   while (g_ascii_isspace (*s))
2006     s++;
2007   if (*s == end) {
2008     s++;
2009     *after = s;
2010     return TRUE;
2011   }
2013   ret = gst_structure_parse_value (s, &s, &list_value, type);
2014   if (ret == FALSE)
2015     return FALSE;
2017   g_array_append_val (array, list_value);
2019   while (g_ascii_isspace (*s))
2020     s++;
2022   while (*s != end) {
2023     if (*s != ',')
2024       return FALSE;
2025     s++;
2027     while (g_ascii_isspace (*s))
2028       s++;
2030     memset (&list_value, 0, sizeof (list_value));
2031     ret = gst_structure_parse_value (s, &s, &list_value, type);
2032     if (ret == FALSE)
2033       return FALSE;
2035     g_array_append_val (array, list_value);
2036     while (g_ascii_isspace (*s))
2037       s++;
2038   }
2040   s++;
2042   *after = s;
2043   return TRUE;
2046 static gboolean
2047 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
2049   return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
2050       '{', '}');
2053 static gboolean
2054 gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
2055     GType type)
2057   return gst_structure_parse_any_list (s, after, value, type,
2058       GST_TYPE_ARRAY, '<', '>');
2061 static gboolean
2062 gst_structure_parse_simple_string (gchar * str, gchar ** end)
2064   char *s = str;
2066   while (G_LIKELY (GST_ASCII_IS_STRING (*s))) {
2067     s++;
2068   }
2070   *end = s;
2072   return (s != str);
2075 static gboolean
2076 gst_structure_parse_field (gchar * str,
2077     gchar ** after, GstStructureField * field)
2079   gchar *name;
2080   gchar *name_end;
2081   gchar *s;
2082   gchar c;
2084   s = str;
2086   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
2087     s++;
2088   name = s;
2089   if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &name_end))) {
2090     GST_WARNING ("failed to parse simple string, str=%s", str);
2091     return FALSE;
2092   }
2094   s = name_end;
2095   while (g_ascii_isspace (*s) || (s[0] == '\\' && g_ascii_isspace (s[1])))
2096     s++;
2098   if (G_UNLIKELY (*s != '=')) {
2099     GST_WARNING ("missing assignment operator in the field, str=%s", str);
2100     return FALSE;
2101   }
2102   s++;
2104   c = *name_end;
2105   *name_end = '\0';
2106   field->name = g_quark_from_string (name);
2107   GST_DEBUG ("trying field name '%s'", name);
2108   *name_end = c;
2110   if (G_UNLIKELY (!gst_structure_parse_value (s, &s, &field->value,
2111               G_TYPE_INVALID))) {
2112     GST_WARNING ("failed to parse value %s", str);
2113     return FALSE;
2114   }
2116   *after = s;
2117   return TRUE;
2120 static gboolean
2121 gst_structure_parse_value (gchar * str,
2122     gchar ** after, GValue * value, GType default_type)
2124   gchar *type_name;
2125   gchar *type_end;
2126   gchar *value_s;
2127   gchar *value_end;
2128   gchar *s;
2129   gchar c;
2130   int ret = 0;
2131   GType type = default_type;
2133   s = str;
2134   while (g_ascii_isspace (*s))
2135     s++;
2137   /* check if there's a (type_name) 'cast' */
2138   type_name = NULL;
2139   if (*s == '(') {
2140     s++;
2141     while (g_ascii_isspace (*s))
2142       s++;
2143     type_name = s;
2144     if (G_UNLIKELY (!gst_structure_parse_simple_string (s, &type_end)))
2145       return FALSE;
2146     s = type_end;
2147     while (g_ascii_isspace (*s))
2148       s++;
2149     if (G_UNLIKELY (*s != ')'))
2150       return FALSE;
2151     s++;
2152     while (g_ascii_isspace (*s))
2153       s++;
2155     c = *type_end;
2156     *type_end = 0;
2157     type = gst_structure_gtype_from_abbr (type_name);
2158     GST_DEBUG ("trying type name '%s'", type_name);
2159     *type_end = c;
2161     if (G_UNLIKELY (type == G_TYPE_INVALID)) {
2162       GST_WARNING ("invalid type");
2163       return FALSE;
2164     }
2165   }
2167   while (g_ascii_isspace (*s))
2168     s++;
2169   if (*s == '[') {
2170     ret = gst_structure_parse_range (s, &s, value, type);
2171   } else if (*s == '{') {
2172     ret = gst_structure_parse_list (s, &s, value, type);
2173   } else if (*s == '<') {
2174     ret = gst_structure_parse_array (s, &s, value, type);
2175   } else {
2176     value_s = s;
2178     if (G_UNLIKELY (type == G_TYPE_INVALID)) {
2179       GType try_types[] =
2180           { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, G_TYPE_BOOLEAN,
2181         G_TYPE_STRING
2182       };
2183       int i;
2185       if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s, TRUE)))
2186         return FALSE;
2187       /* Set NULL terminator for deserialization */
2188       c = *value_end;
2189       *value_end = '\0';
2191       for (i = 0; i < G_N_ELEMENTS (try_types); i++) {
2192         g_value_init (value, try_types[i]);
2193         ret = gst_value_deserialize (value, value_s);
2194         if (ret)
2195           break;
2196         g_value_unset (value);
2197       }
2198     } else {
2199       g_value_init (value, type);
2201       if (G_UNLIKELY (!gst_structure_parse_string (s, &value_end, &s,
2202                   (type != G_TYPE_STRING))))
2203         return FALSE;
2204       /* Set NULL terminator for deserialization */
2205       c = *value_end;
2206       *value_end = '\0';
2208       ret = gst_value_deserialize (value, value_s);
2209       if (G_UNLIKELY (!ret))
2210         g_value_unset (value);
2211     }
2212     *value_end = c;
2213   }
2215   *after = s;
2217   return ret;
2220 /**
2221  * gst_structure_from_string:
2222  * @string: a string representation of a #GstStructure.
2223  * @end: (out) (allow-none): pointer to store the end of the string in.
2224  *
2225  * Creates a #GstStructure from a string representation.
2226  * If end is not NULL, a pointer to the place inside the given string
2227  * where parsing ended will be returned.
2228  *
2229  * Free-function: gst_structure_free
2230  *
2231  * Returns: (transfer full): a new #GstStructure or NULL when the string could
2232  *     not be parsed. Free with gst_structure_free() after use.
2233  */
2234 GstStructure *
2235 gst_structure_from_string (const gchar * string, gchar ** end)
2237   char *name;
2238   char *copy;
2239   char *w;
2240   char *r;
2241   char save;
2242   GstStructure *structure = NULL;
2243   GstStructureField field;
2245   g_return_val_if_fail (string != NULL, NULL);
2247   copy = g_strdup (string);
2248   r = copy;
2250   /* skip spaces (FIXME: _isspace treats tabs and newlines as space!) */
2251   while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2252               && g_ascii_isspace (r[1]))))
2253     r++;
2255   name = r;
2256   if (G_UNLIKELY (!gst_structure_parse_string (r, &w, &r, TRUE))) {
2257     GST_WARNING ("Failed to parse structure string '%s'", string);
2258     goto error;
2259   }
2261   save = *w;
2262   *w = '\0';
2263   structure = gst_structure_empty_new (name);
2264   *w = save;
2266   if (G_UNLIKELY (structure == NULL))
2267     goto error;
2269   do {
2270     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2271                 && g_ascii_isspace (r[1]))))
2272       r++;
2273     if (*r == ';') {
2274       /* end of structure, get the next char and finish */
2275       r++;
2276       break;
2277     }
2278     if (*r == '\0') {
2279       /* accept \0 as end delimiter */
2280       break;
2281     }
2282     if (G_UNLIKELY (*r != ',')) {
2283       GST_WARNING ("Failed to find delimiter, r=%s", r);
2284       goto error;
2285     }
2286     r++;
2287     while (*r && (g_ascii_isspace (*r) || (r[0] == '\\'
2288                 && g_ascii_isspace (r[1]))))
2289       r++;
2291     memset (&field, 0, sizeof (field));
2292     if (G_UNLIKELY (!gst_structure_parse_field (r, &r, &field))) {
2293       GST_WARNING ("Failed to parse field, r=%s", r);
2294       goto error;
2295     }
2296     gst_structure_set_field (structure, &field);
2297   } while (TRUE);
2299   if (end)
2300     *end = (char *) string + (r - copy);
2301   else if (*r)
2302     g_warning ("gst_structure_from_string did not consume whole string,"
2303         " but caller did not provide end pointer (\"%s\")", string);
2305   g_free (copy);
2306   return structure;
2308 error:
2309   if (structure)
2310     gst_structure_free (structure);
2311   g_free (copy);
2312   return NULL;
2315 static void
2316 gst_structure_transform_to_string (const GValue * src_value,
2317     GValue * dest_value)
2319   g_return_if_fail (src_value != NULL);
2320   g_return_if_fail (dest_value != NULL);
2322   dest_value->data[0].v_pointer =
2323       gst_structure_to_string (src_value->data[0].v_pointer);
2326 static GstStructure *
2327 gst_structure_copy_conditional (const GstStructure * structure)
2329   if (structure)
2330     return gst_structure_copy (structure);
2331   return NULL;
2334 /* fixate utility functions */
2336 /**
2337  * gst_structure_fixate_field_nearest_int:
2338  * @structure: a #GstStructure
2339  * @field_name: a field in @structure
2340  * @target: the target value of the fixation
2341  *
2342  * Fixates a #GstStructure by changing the given field to the nearest
2343  * integer to @target that is a subset of the existing field.
2344  *
2345  * Returns: TRUE if the structure could be fixated
2346  */
2347 gboolean
2348 gst_structure_fixate_field_nearest_int (GstStructure * structure,
2349     const char *field_name, int target)
2351   const GValue *value;
2353   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2354   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2356   value = gst_structure_get_value (structure, field_name);
2358   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
2359     /* already fixed */
2360     return FALSE;
2361   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
2362     int x;
2364     x = gst_value_get_int_range_min (value);
2365     if (target < x)
2366       target = x;
2367     x = gst_value_get_int_range_max (value);
2368     if (target > x)
2369       target = x;
2370     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
2371     return TRUE;
2372   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2373     const GValue *list_value;
2374     int i, n;
2375     int best = 0;
2376     int best_index = -1;
2378     n = gst_value_list_get_size (value);
2379     for (i = 0; i < n; i++) {
2380       list_value = gst_value_list_get_value (value, i);
2381       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
2382         int x = gst_g_value_get_int_unchecked (list_value);
2384         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2385           best_index = i;
2386           best = x;
2387         }
2388       }
2389     }
2390     if (best_index != -1) {
2391       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
2392       return TRUE;
2393     }
2394     return FALSE;
2395   }
2397   return FALSE;
2400 /**
2401  * gst_structure_fixate_field_nearest_double:
2402  * @structure: a #GstStructure
2403  * @field_name: a field in @structure
2404  * @target: the target value of the fixation
2405  *
2406  * Fixates a #GstStructure by changing the given field to the nearest
2407  * double to @target that is a subset of the existing field.
2408  *
2409  * Returns: TRUE if the structure could be fixated
2410  */
2411 gboolean
2412 gst_structure_fixate_field_nearest_double (GstStructure * structure,
2413     const char *field_name, double target)
2415   const GValue *value;
2417   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2418   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2420   value = gst_structure_get_value (structure, field_name);
2422   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
2423     /* already fixed */
2424     return FALSE;
2425   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
2426     double x;
2428     x = gst_value_get_double_range_min (value);
2429     if (target < x)
2430       target = x;
2431     x = gst_value_get_double_range_max (value);
2432     if (target > x)
2433       target = x;
2434     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
2435     return TRUE;
2436   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2437     const GValue *list_value;
2438     int i, n;
2439     double best = 0;
2440     int best_index = -1;
2442     n = gst_value_list_get_size (value);
2443     for (i = 0; i < n; i++) {
2444       list_value = gst_value_list_get_value (value, i);
2445       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
2446         double x = gst_g_value_get_double_unchecked (list_value);
2448         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
2449           best_index = i;
2450           best = x;
2451         }
2452       }
2453     }
2454     if (best_index != -1) {
2455       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
2456       return TRUE;
2457     }
2458     return FALSE;
2459   }
2461   return FALSE;
2465 /**
2466  * gst_structure_fixate_field_boolean:
2467  * @structure: a #GstStructure
2468  * @field_name: a field in @structure
2469  * @target: the target value of the fixation
2470  *
2471  * Fixates a #GstStructure by changing the given @field_name field to the given
2472  * @target boolean if that field is not fixed yet.
2473  *
2474  * Returns: TRUE if the structure could be fixated
2475  */
2476 gboolean
2477 gst_structure_fixate_field_boolean (GstStructure * structure,
2478     const char *field_name, gboolean target)
2480   const GValue *value;
2482   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2483   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2485   value = gst_structure_get_value (structure, field_name);
2487   if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
2488     /* already fixed */
2489     return FALSE;
2490   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2491     const GValue *list_value;
2492     int i, n;
2493     int best = 0;
2494     int best_index = -1;
2496     n = gst_value_list_get_size (value);
2497     for (i = 0; i < n; i++) {
2498       list_value = gst_value_list_get_value (value, i);
2499       if (G_VALUE_TYPE (list_value) == G_TYPE_BOOLEAN) {
2500         gboolean x = gst_g_value_get_boolean_unchecked (list_value);
2502         if (best_index == -1 || x == target) {
2503           best_index = i;
2504           best = x;
2505         }
2506       }
2507     }
2508     if (best_index != -1) {
2509       gst_structure_set (structure, field_name, G_TYPE_BOOLEAN, best, NULL);
2510       return TRUE;
2511     }
2512     return FALSE;
2513   }
2515   return FALSE;
2518 /**
2519  * gst_structure_fixate_field_string:
2520  * @structure: a #GstStructure
2521  * @field_name: a field in @structure
2522  * @target: the target value of the fixation
2523  *
2524  * Fixates a #GstStructure by changing the given @field_name field to the given
2525  * @target string if that field is not fixed yet.
2526  *
2527  * Returns: TRUE if the structure could be fixated
2528  *
2529  * Since: 0.10.30
2530  */
2531 gboolean
2532 gst_structure_fixate_field_string (GstStructure * structure,
2533     const gchar * field_name, const gchar * target)
2535   const GValue *value;
2537   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2538   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2540   value = gst_structure_get_value (structure, field_name);
2542   if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
2543     /* already fixed */
2544     return FALSE;
2545   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2546     const GValue *list_value;
2547     int i, n;
2548     const gchar *best = NULL;
2549     int best_index = -1;
2551     n = gst_value_list_get_size (value);
2552     for (i = 0; i < n; i++) {
2553       list_value = gst_value_list_get_value (value, i);
2554       if (G_VALUE_TYPE (list_value) == G_TYPE_STRING) {
2555         const gchar *x = g_value_get_string (list_value);
2557         if (best_index == -1 || g_str_equal (x, target)) {
2558           best_index = i;
2559           best = x;
2560         }
2561       }
2562     }
2563     if (best_index != -1) {
2564       gst_structure_set (structure, field_name, G_TYPE_STRING, best, NULL);
2565       return TRUE;
2566     }
2567     return FALSE;
2568   }
2570   return FALSE;
2573 /**
2574  * gst_structure_fixate_field_nearest_fraction:
2575  * @structure: a #GstStructure
2576  * @field_name: a field in @structure
2577  * @target_numerator: The numerator of the target value of the fixation
2578  * @target_denominator: The denominator of the target value of the fixation
2579  *
2580  * Fixates a #GstStructure by changing the given field to the nearest
2581  * fraction to @target_numerator/@target_denominator that is a subset
2582  * of the existing field.
2583  *
2584  * Returns: TRUE if the structure could be fixated
2585  */
2586 gboolean
2587 gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
2588     const char *field_name, const gint target_numerator,
2589     const gint target_denominator)
2591   const GValue *value;
2593   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
2594   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
2596   value = gst_structure_get_value (structure, field_name);
2598   if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
2599     /* already fixed */
2600     return FALSE;
2601   } else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
2602     const GValue *x, *new_value;
2603     GValue target = { 0 };
2604     g_value_init (&target, GST_TYPE_FRACTION);
2605     gst_value_set_fraction (&target, target_numerator, target_denominator);
2607     new_value = &target;
2608     x = gst_value_get_fraction_range_min (value);
2609     if (gst_value_compare (&target, x) == GST_VALUE_LESS_THAN)
2610       new_value = x;
2611     x = gst_value_get_fraction_range_max (value);
2612     if (gst_value_compare (&target, x) == GST_VALUE_GREATER_THAN)
2613       new_value = x;
2615     gst_structure_set_value (structure, field_name, new_value);
2616     g_value_unset (&target);
2617     return TRUE;
2618   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
2619     const GValue *list_value;
2620     int i, n;
2621     const GValue *best = NULL;
2622     gdouble target;
2623     gdouble cur_diff;
2624     gdouble best_diff = G_MAXDOUBLE;
2626     target = (gdouble) target_numerator / (gdouble) target_denominator;
2628     GST_DEBUG ("target %g, best %g", target, best_diff);
2630     best = NULL;
2632     n = gst_value_list_get_size (value);
2633     for (i = 0; i < n; i++) {
2634       list_value = gst_value_list_get_value (value, i);
2635       if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
2636         gint num, denom;
2637         gdouble list_double;
2639         num = gst_value_get_fraction_numerator (list_value);
2640         denom = gst_value_get_fraction_denominator (list_value);
2642         list_double = ((gdouble) num / (gdouble) denom);
2643         cur_diff = target - list_double;
2645         GST_DEBUG ("curr diff %g, list %g", cur_diff, list_double);
2647         if (cur_diff < 0)
2648           cur_diff = -cur_diff;
2650         if (!best || cur_diff < best_diff) {
2651           GST_DEBUG ("new best %g", list_double);
2652           best = list_value;
2653           best_diff = cur_diff;
2654         }
2655       }
2656     }
2657     if (best != NULL) {
2658       gst_structure_set_value (structure, field_name, best);
2659       return TRUE;
2660     }
2661   }
2663   return FALSE;
2666 /* our very own version of G_VALUE_LCOPY that allows NULL return locations
2667  * (useful for message parsing functions where the return location is user
2668  * supplied and the user may pass NULL if the value isn't of interest) */
2669 #define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname)           \
2670 G_STMT_START {                                                                \
2671   const GValue *_value = (value);                                             \
2672   guint _flags = (flags);                                                     \
2673   GType _value_type = G_VALUE_TYPE (_value);                                  \
2674   GTypeValueTable *_vtable = g_type_value_table_peek (_value_type);           \
2675   gchar *_lcopy_format = _vtable->lcopy_format;                               \
2676   GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };      \
2677   guint _n_values = 0;                                                        \
2678                                                                               \
2679   while (*_lcopy_format != '\0') {                                            \
2680     g_assert (*_lcopy_format == G_VALUE_COLLECT_POINTER);                     \
2681     _cvalues[_n_values++].v_pointer = va_arg ((var_args), gpointer);          \
2682     _lcopy_format++;                                                          \
2683   }                                                                           \
2684   if (_n_values == 2 && !!_cvalues[0].v_pointer != !!_cvalues[1].v_pointer) { \
2685     *(__error) = g_strdup_printf ("either all or none of the return "         \
2686         "locations for field '%s' need to be NULL", fieldname);               \
2687   } else if (_cvalues[0].v_pointer != NULL) {                                 \
2688     *(__error) = _vtable->lcopy_value (_value, _n_values, _cvalues, _flags);  \
2689   }                                                                           \
2690 } G_STMT_END
2692 /**
2693  * gst_structure_get_valist:
2694  * @structure: a #GstStructure
2695  * @first_fieldname: the name of the first field to read
2696  * @args: variable arguments
2697  *
2698  * Parses the variable arguments and reads fields from @structure accordingly.
2699  * valist-variant of gst_structure_get(). Look at the documentation of
2700  * gst_structure_get() for more details.
2701  *
2702  * Returns: TRUE, or FALSE if there was a problem reading any of the fields
2703  *
2704  * Since: 0.10.24
2705  */
2706 gboolean
2707 gst_structure_get_valist (const GstStructure * structure,
2708     const char *first_fieldname, va_list args)
2710   const char *field_name;
2711   GType expected_type = G_TYPE_INVALID;
2713   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2714   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2716   field_name = first_fieldname;
2717   while (field_name) {
2718     const GValue *val = NULL;
2719     gchar *err = NULL;
2721     expected_type = va_arg (args, GType);
2723     val = gst_structure_get_value (structure, field_name);
2725     if (val == NULL)
2726       goto no_such_field;
2728     if (G_VALUE_TYPE (val) != expected_type)
2729       goto wrong_type;
2731     GST_VALUE_LCOPY (val, args, 0, &err, field_name);
2732     if (err) {
2733       g_warning ("%s: %s", G_STRFUNC, err);
2734       g_free (err);
2735       return FALSE;
2736     }
2738     field_name = va_arg (args, const gchar *);
2739   }
2741   return TRUE;
2743 /* ERRORS */
2744 no_such_field:
2745   {
2746     GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2747         field_name, structure);
2748     return FALSE;
2749   }
2750 wrong_type:
2751   {
2752     GST_WARNING ("Expected field '%s' in structure to be of type '%s', but "
2753         "field was of type '%s': %" GST_PTR_FORMAT, field_name,
2754         GST_STR_NULL (g_type_name (expected_type)),
2755         G_VALUE_TYPE_NAME (gst_structure_get_value (structure, field_name)),
2756         structure);
2757     return FALSE;
2758   }
2761 /**
2762  * gst_structure_id_get_valist:
2763  * @structure: a #GstStructure
2764  * @first_field_id: the quark of the first field to read
2765  * @args: variable arguments
2766  *
2767  * Parses the variable arguments and reads fields from @structure accordingly.
2768  * valist-variant of gst_structure_id_get(). Look at the documentation of
2769  * gst_structure_id_get() for more details.
2770  *
2771  * Returns: TRUE, or FALSE if there was a problem reading any of the fields
2772  *
2773  * Since: 0.10.24
2774  */
2775 gboolean
2776 gst_structure_id_get_valist (const GstStructure * structure,
2777     GQuark first_field_id, va_list args)
2779   GQuark field_id;
2780   GType expected_type = G_TYPE_INVALID;
2782   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2783   g_return_val_if_fail (first_field_id != 0, FALSE);
2785   field_id = first_field_id;
2786   while (field_id) {
2787     const GValue *val = NULL;
2788     gchar *err = NULL;
2790     expected_type = va_arg (args, GType);
2792     val = gst_structure_id_get_value (structure, field_id);
2794     if (val == NULL)
2795       goto no_such_field;
2797     if (G_VALUE_TYPE (val) != expected_type)
2798       goto wrong_type;
2800     GST_VALUE_LCOPY (val, args, 0, &err, g_quark_to_string (field_id));
2801     if (err) {
2802       g_warning ("%s: %s", G_STRFUNC, err);
2803       g_free (err);
2804       return FALSE;
2805     }
2807     field_id = va_arg (args, GQuark);
2808   }
2810   return TRUE;
2812 /* ERRORS */
2813 no_such_field:
2814   {
2815     GST_WARNING ("Expected field '%s' in structure: %" GST_PTR_FORMAT,
2816         GST_STR_NULL (g_quark_to_string (field_id)), structure);
2817     return FALSE;
2818   }
2819 wrong_type:
2820   {
2821     GST_WARNING ("Expected field '%s' in structure to be of type '%s', but "
2822         "field was of type '%s': %" GST_PTR_FORMAT,
2823         g_quark_to_string (field_id),
2824         GST_STR_NULL (g_type_name (expected_type)),
2825         G_VALUE_TYPE_NAME (gst_structure_id_get_value (structure, field_id)),
2826         structure);
2827     return FALSE;
2828   }
2831 /**
2832  * gst_structure_get:
2833  * @structure: a #GstStructure
2834  * @first_fieldname: the name of the first field to read
2835  * @...: variable arguments
2836  *
2837  * Parses the variable arguments and reads fields from @structure accordingly.
2838  * Variable arguments should be in the form field name, field type
2839  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2840  * The last variable argument should be NULL.
2841  *
2842  * For refcounted (mini)objects you will acquire your own reference which
2843  * you must release with a suitable _unref() when no longer needed. For
2844  * strings and boxed types you will acquire a copy which you will need to
2845  * release with either g_free() or the suitable function for the boxed type.
2846  *
2847  * Returns: FALSE if there was a problem reading any of the fields (e.g.
2848  *     because the field requested did not exist, or was of a type other
2849  *     than the type specified), otherwise TRUE.
2850  *
2851  * Since: 0.10.24
2852  */
2853 gboolean
2854 gst_structure_get (const GstStructure * structure, const char *first_fieldname,
2855     ...)
2857   gboolean ret;
2858   va_list args;
2860   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2861   g_return_val_if_fail (first_fieldname != NULL, FALSE);
2863   va_start (args, first_fieldname);
2864   ret = gst_structure_get_valist (structure, first_fieldname, args);
2865   va_end (args);
2867   return ret;
2870 /**
2871  * gst_structure_id_get:
2872  * @structure: a #GstStructure
2873  * @first_field_id: the quark of the first field to read
2874  * @...: variable arguments
2875  *
2876  * Parses the variable arguments and reads fields from @structure accordingly.
2877  * Variable arguments should be in the form field id quark, field type
2878  * (as a GType), pointer(s) to a variable(s) to hold the return value(s).
2879  * The last variable argument should be NULL (technically it should be a
2880  * 0 quark, but we require NULL so compilers that support it can check for
2881  * the NULL terminator and warn if it's not there).
2882  *
2883  * This function is just like gst_structure_get() only that it is slightly
2884  * more efficient since it saves the string-to-quark lookup in the global
2885  * quark hashtable.
2886  *
2887  * For refcounted (mini)objects you will acquire your own reference which
2888  * you must release with a suitable _unref() when no longer needed. For
2889  * strings and boxed types you will acquire a copy which you will need to
2890  * release with either g_free() or the suitable function for the boxed type.
2891  *
2892  * Returns: FALSE if there was a problem reading any of the fields (e.g.
2893  *     because the field requested did not exist, or was of a type other
2894  *     than the type specified), otherwise TRUE.
2895  *
2896  * Since: 0.10.24
2897  */
2898 gboolean
2899 gst_structure_id_get (const GstStructure * structure, GQuark first_field_id,
2900     ...)
2902   gboolean ret;
2903   va_list args;
2905   g_return_val_if_fail (GST_IS_STRUCTURE (structure), FALSE);
2906   g_return_val_if_fail (first_field_id != 0, FALSE);
2908   va_start (args, first_field_id);
2909   ret = gst_structure_id_get_valist (structure, first_field_id, args);
2910   va_end (args);
2912   return ret;
2915 static gboolean
2916 gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
2917     gpointer data)
2919   const GstStructure *struct1 = (const GstStructure *) data;
2920   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
2922   if (G_UNLIKELY (val1 == NULL))
2923     return FALSE;
2924   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
2925     return TRUE;
2926   }
2928   return FALSE;
2931 /**
2932  * gst_structure_is_equal:
2933  * @structure1: a #GstStructure.
2934  * @structure2: a #GstStructure.
2935  *
2936  * Tests if the two #GstStructure are equal.
2937  *
2938  * Returns: TRUE if the two structures have the same name and field.
2939  *
2940  * Since: 0.10.36
2941  **/
2942 gboolean
2943 gst_structure_is_equal (const GstStructure * structure1,
2944     const GstStructure * structure2)
2946   g_return_val_if_fail (GST_IS_STRUCTURE (structure1), FALSE);
2947   g_return_val_if_fail (GST_IS_STRUCTURE (structure2), FALSE);
2949   if (G_UNLIKELY (structure1 == structure2))
2950     return TRUE;
2952   if (structure1->name != structure2->name) {
2953     return FALSE;
2954   }
2955   if (structure1->fields->len != structure2->fields->len) {
2956     return FALSE;
2957   }
2959   return gst_structure_foreach (structure1, gst_structure_is_equal_foreach,
2960       (gpointer) structure2);
2964 typedef struct
2966   GstStructure *dest;
2967   const GstStructure *intersect;
2969 IntersectData;
2971 static gboolean
2972 gst_structure_intersect_field1 (GQuark id, const GValue * val1, gpointer data)
2974   IntersectData *idata = (IntersectData *) data;
2975   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
2977   if (G_UNLIKELY (val2 == NULL)) {
2978     gst_structure_id_set_value (idata->dest, id, val1);
2979   } else {
2980     GValue dest_value = { 0 };
2981     if (gst_value_intersect (&dest_value, val1, val2)) {
2982       gst_structure_id_set_value (idata->dest, id, &dest_value);
2983       g_value_unset (&dest_value);
2984     } else {
2985       return FALSE;
2986     }
2987   }
2988   return TRUE;
2991 static gboolean
2992 gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
2994   IntersectData *idata = (IntersectData *) data;
2995   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
2997   if (G_UNLIKELY (val2 == NULL)) {
2998     gst_structure_id_set_value (idata->dest, id, val1);
2999   }
3000   return TRUE;
3003 /**
3004  * gst_structure_intersect:
3005  * @struct1: a #GstStructure
3006  * @struct2: a #GstStructure
3007  *
3008  * Interesects @struct1 and @struct2 and returns the intersection.
3009  *
3010  * Returns: Intersection of @struct1 and @struct2
3011  *
3012  * Since: 0.10.36
3013  */
3014 GstStructure *
3015 gst_structure_intersect (const GstStructure * struct1,
3016     const GstStructure * struct2)
3018   IntersectData data;
3020   g_assert (struct1 != NULL);
3021   g_assert (struct2 != NULL);
3023   if (G_UNLIKELY (struct1->name != struct2->name))
3024     return NULL;
3026   /* copy fields from struct1 which we have not in struct2 to target
3027    * intersect if we have the field in both */
3028   data.dest = gst_structure_id_empty_new (struct1->name);
3029   data.intersect = struct2;
3030   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
3031               gst_structure_intersect_field1, &data)))
3032     goto error;
3034   /* copy fields from struct2 which we have not in struct1 to target */
3035   data.intersect = struct1;
3036   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
3037               gst_structure_intersect_field2, &data)))
3038     goto error;
3040   return data.dest;
3042 error:
3043   gst_structure_free (data.dest);
3044   return NULL;
3047 static gboolean
3048 gst_caps_structure_can_intersect_field (GQuark id, const GValue * val1,
3049     gpointer data)
3051   GstStructure *other = (GstStructure *) data;
3052   const GValue *val2 = gst_structure_id_get_value (other, id);
3054   if (G_LIKELY (val2)) {
3055     if (!gst_value_can_intersect (val1, val2)) {
3056       return FALSE;
3057     } else {
3058       gint eq = gst_value_compare (val1, val2);
3060       if (eq == GST_VALUE_UNORDERED) {
3061         /* we need to try interseting */
3062         if (!gst_value_intersect (NULL, val1, val2)) {
3063           return FALSE;
3064         }
3065       } else if (eq != GST_VALUE_EQUAL) {
3066         return FALSE;
3067       }
3068     }
3069   }
3070   return TRUE;
3073 /**
3074  * gst_structure_can_intersect:
3075  * @struct1: a #GstStructure
3076  * @struct2: a #GstStructure
3077  *
3078  * Tries intersecting @struct1 and @struct2 and reports whether the result
3079  * would not be empty.
3080  *
3081  * Returns: %TRUE if intersection would not be empty
3082  *
3083  * Since: 0.10.36
3084  */
3085 gboolean
3086 gst_structure_can_intersect (const GstStructure * struct1,
3087     const GstStructure * struct2)
3089   g_return_val_if_fail (GST_IS_STRUCTURE (struct1), FALSE);
3090   g_return_val_if_fail (GST_IS_STRUCTURE (struct2), FALSE);
3092   if (G_UNLIKELY (struct1->name != struct2->name))
3093     return FALSE;
3095   /* tries to intersect if we have the field in both */
3096   return gst_structure_foreach ((GstStructure *) struct1,
3097       gst_caps_structure_can_intersect_field, (gpointer) struct2);
3100 static gboolean
3101 gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
3102     gpointer user_data)
3104   GstStructure *superset = user_data;
3105   const GValue *other;
3106   int comparison;
3108   if (!(other = gst_structure_id_get_value (superset, field_id)))
3109     /* field is missing in the superset => is subset */
3110     return TRUE;
3112   comparison = gst_value_compare (other, value);
3114   /* equal values are subset */
3115   if (comparison == GST_VALUE_EQUAL)
3116     return TRUE;
3118   /* ordered, but unequal, values are not */
3119   if (comparison != GST_VALUE_UNORDERED)
3120     return FALSE;
3122   /*
3123    * 1 - [1,2] = empty
3124    * -> !subset
3125    *
3126    * [1,2] - 1 = 2
3127    *  -> 1 - [1,2] = empty
3128    *  -> subset
3129    *
3130    * [1,3] - [1,2] = 3
3131    * -> [1,2] - [1,3] = empty
3132    * -> subset
3133    *
3134    * {1,2} - {1,3} = 2
3135    * -> {1,3} - {1,2} = 3
3136    * -> !subset
3137    *
3138    *  First caps subtraction needs to return a non-empty set, second
3139    *  subtractions needs to give en empty set.
3140    *  Both substractions are switched below, as it's faster that way.
3141    */
3142   if (!gst_value_subtract (NULL, value, other)) {
3143     if (gst_value_subtract (NULL, other, value)) {
3144       return TRUE;
3145     }
3146   }
3147   return FALSE;
3150 /**
3151  * gst_structure_is_subset:
3152  * @subset: a #GstStructure
3153  * @superset: a potentially greater #GstStructure
3154  *
3155  * Checks if @subset is a subset of @superset, i.e. has the same
3156  * structure name and for all fields that are existing in @superset,
3157  * @subset has a value that is a subset of the value in @superset.
3158  *
3159  * Returns: %TRUE if @subset is a subset of @superset
3160  *
3161  * Since: 0.10.36
3162  */
3163 gboolean
3164 gst_structure_is_subset (const GstStructure * subset,
3165     const GstStructure * superset)
3167   if ((superset->name != subset->name) ||
3168       (gst_structure_n_fields (superset) > gst_structure_n_fields (subset)))
3169     return FALSE;
3171   return gst_structure_foreach ((GstStructure *) subset,
3172       gst_caps_structure_is_subset_field, (gpointer) superset);