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