source: trunk/third/gstreamer/gst/gststructure.c @ 21448

Revision 21448, 36.0 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21447, which included commits to RCS files with non-trunk default branches.
Line 
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 */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include <string.h>
27
28#include "gst_private.h"
29#include <gst/gst.h>
30#include <gobject/gvaluecollector.h>
31
32typedef struct _GstStructureField GstStructureField;
33
34struct _GstStructureField
35{
36  GQuark name;
37  GValue value;
38};
39
40#define GST_STRUCTURE_FIELD(structure, index) \
41    &g_array_index((structure)->fields, GstStructureField, (index))
42
43static void gst_structure_set_field (GstStructure * structure,
44    GstStructureField * field);
45static GstStructureField *gst_structure_get_field (const GstStructure *
46    structure, const gchar * fieldname);
47static GstStructureField *gst_structure_id_get_field (const GstStructure *
48    structure, GQuark field);
49static void gst_structure_transform_to_string (const GValue * src_value,
50    GValue * dest_value);
51static GstStructure *gst_structure_copy_conditional (const GstStructure *
52    structure);
53static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
54    GValue * value, GType default_type);
55static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
56
57GType
58gst_structure_get_type (void)
59{
60  static GType gst_structure_type;
61
62  if (!gst_structure_type) {
63    gst_structure_type = g_boxed_type_register_static ("GstStructure",
64        (GBoxedCopyFunc) gst_structure_copy_conditional,
65        (GBoxedFreeFunc) gst_structure_free);
66
67    g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
68        gst_structure_transform_to_string);
69  }
70
71  return gst_structure_type;
72}
73
74static GstStructure *
75gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
76{
77  GstStructure *structure;
78
79  structure = g_new0 (GstStructure, 1);
80  structure->type = gst_structure_get_type ();
81  structure->name = quark;
82  structure->fields =
83      g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc);
84
85  return structure;
86}
87
88/**
89 * gst_structure_id_empty_new:
90 * @quark: name of new structure
91 *
92 * Creates a new, empty #GstStructure with the given name.
93 *
94 * Returns: a new, empty #GstStructure
95 */
96GstStructure *
97gst_structure_id_empty_new (GQuark quark)
98{
99  g_return_val_if_fail (quark != 0, NULL);
100
101  return gst_structure_id_empty_new_with_size (quark, 0);
102}
103
104/**
105 * gst_structure_empty_new:
106 * @name: name of new structure
107 *
108 * Creates a new, empty #GstStructure with the given name.
109 *
110 * Returns: a new, empty #GstStructure
111 */
112GstStructure *
113gst_structure_empty_new (const gchar * name)
114{
115  g_return_val_if_fail (name != NULL, NULL);
116
117  return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
118}
119
120/**
121 * gst_structure_new:
122 * @name: name of new structure
123 * @firstfield: name of first field to set
124 * @...: additional arguments
125 *
126 * Creates a new #GstStructure with the given name.  Parses the
127 * list of variable arguments and sets fields to the values listed.
128 * Variable arguments should be passed as field name, field type,
129 * and value.  Last variable argument should be NULL.
130 *
131 * Returns: a new #GstStructure
132 */
133GstStructure *
134gst_structure_new (const gchar * name, const gchar * firstfield, ...)
135{
136  GstStructure *structure;
137  va_list varargs;
138
139  g_return_val_if_fail (name != NULL, NULL);
140
141  va_start (varargs, firstfield);
142
143  structure = gst_structure_new_valist (name, firstfield, varargs);
144
145  va_end (varargs);
146
147  return structure;
148}
149
150/**
151 * gst_structure_new_valist:
152 * @name: name of new structure
153 * @firstfield: name of first field to set
154 * @varargs: variable argument list
155 *
156 * Creates a new #GstStructure with the given name.  Structure fields
157 * are set according to the varargs in a manner similar to
158 * @gst_structure_new.
159 *
160 * Returns: a new #GstStructure
161 */
162GstStructure *
163gst_structure_new_valist (const gchar * name,
164    const gchar * firstfield, va_list varargs)
165{
166  GstStructure *structure;
167
168  g_return_val_if_fail (name != NULL, NULL);
169
170  structure = gst_structure_empty_new (name);
171  gst_structure_set_valist (structure, firstfield, varargs);
172
173  return structure;
174}
175
176/**
177 * gst_structure_copy:
178 * @structure: a #GstStructure to duplicate
179 *
180 * Duplicates a #GstStructure and all its fields and values.
181 *
182 * Returns: a new #GstStructure.
183 */
184GstStructure *
185gst_structure_copy (const GstStructure * structure)
186{
187  GstStructure *new_structure;
188  GstStructureField *field;
189  int i;
190
191  g_return_val_if_fail (structure != NULL, NULL);
192
193  new_structure =
194      gst_structure_id_empty_new_with_size (structure->name,
195      structure->fields->len);
196
197  for (i = 0; i < structure->fields->len; i++) {
198    GstStructureField new_field = { 0 };
199
200    field = GST_STRUCTURE_FIELD (structure, i);
201
202    new_field.name = field->name;
203    gst_value_init_and_copy (&new_field.value, &field->value);
204    g_array_append_val (new_structure->fields, new_field);
205  }
206
207  return new_structure;
208}
209
210/**
211 * gst_structure_free:
212 * @structure: the #GstStructure to free
213 *
214 * Frees a #GstStructure and all its fields and values.
215 */
216void
217gst_structure_free (GstStructure * structure)
218{
219  GstStructureField *field;
220  int i;
221
222  g_return_if_fail (structure != NULL);
223
224  for (i = 0; i < structure->fields->len; i++) {
225    field = GST_STRUCTURE_FIELD (structure, i);
226
227    if (G_IS_VALUE (&field->value)) {
228      g_value_unset (&field->value);
229    }
230  }
231  g_array_free (structure->fields, TRUE);
232#ifdef USE_POISONING
233  memset (structure, 0xff, sizeof (GstStructure));
234#endif
235  g_free (structure);
236}
237
238/**
239 * gst_structure_get_name:
240 * @structure: a #GstStructure
241 *
242 * Accessor fuction.
243 *
244 * Returns: the name of the structure.
245 */
246const gchar *
247gst_structure_get_name (const GstStructure * structure)
248{
249  g_return_val_if_fail (structure != NULL, NULL);
250
251  return g_quark_to_string (structure->name);
252}
253
254/**
255 * gst_structure_get_name:
256 * @structure: a #GstStructure
257 *
258 * Accessor fuction.
259 *
260 * Returns: the quark representing the name of the structure.
261 */
262GQuark
263gst_structure_get_name_id (const GstStructure * structure)
264{
265  g_return_val_if_fail (structure != NULL, 0);
266
267  return structure->name;
268}
269
270/**
271 * gst_structure_set_name:
272 * @structure: a #GstStructure
273 * @name: the new name of the structure
274 *
275 * Sets the name of the structure to the given name.  The string
276 * provided is copied before being used.
277 */
278void
279gst_structure_set_name (GstStructure * structure, const gchar * name)
280{
281  g_return_if_fail (structure != NULL);
282  g_return_if_fail (name != NULL);
283
284  structure->name = g_quark_from_string (name);
285}
286
287/**
288 * gst_structure_id_set_value:
289 * @structure: a #GstStructure
290 * @field: a #GQuark representing a field
291 * @value: the new value of the field
292 *
293 * Sets the field with the given ID to the provided value.  If the field
294 * does not exist, it is created.  If the field exists, the previous
295 * value is freed.
296 */
297void
298gst_structure_id_set_value (GstStructure * structure,
299    GQuark field, const GValue * value)
300{
301  GstStructureField gsfield = { 0, {0,} };
302
303  g_return_if_fail (structure != NULL);
304  g_return_if_fail (G_IS_VALUE (value));
305
306  gsfield.name = field;
307  gst_value_init_and_copy (&gsfield.value, value);
308
309  gst_structure_set_field (structure, &gsfield);
310}
311
312/**
313 * gst_structure_set_value:
314 * @structure: a #GstStructure
315 * @fieldname: the name of the field to set
316 * @value: the new value of the field
317 *
318 * Sets the field with the given name to the provided value.  If the field
319 * does not exist, it is created.  If the field exists, the previous
320 * value is freed.
321 */
322void
323gst_structure_set_value (GstStructure * structure,
324    const gchar * fieldname, const GValue * value)
325{
326  g_return_if_fail (structure != NULL);
327  g_return_if_fail (fieldname != NULL);
328  g_return_if_fail (G_IS_VALUE (value));
329
330  gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
331      value);
332}
333
334/**
335 * gst_structure_set:
336 * @structure: a #GstStructure
337 * @fieldname: the name of the field to set
338 * @...: variable arguments
339 *
340 * Parses the variable arguments and sets fields accordingly.
341 * Variable arguments should be in the form field name, field type
342 * (as a GType), value.  The last variable argument should be NULL.
343 */
344void
345gst_structure_set (GstStructure * structure, const gchar * field, ...)
346{
347  va_list varargs;
348
349  g_return_if_fail (structure != NULL);
350
351  va_start (varargs, field);
352
353  gst_structure_set_valist (structure, field, varargs);
354
355  va_end (varargs);
356}
357
358/**
359 * gst_structure_set_valist:
360 * @structure: a #GstStructure
361 * @fieldname: the name of the field to set
362 * @varargs: variable arguments
363 *
364 * va_list form of #gst_structure_set.
365 */
366void
367gst_structure_set_valist (GstStructure * structure,
368    const gchar * fieldname, va_list varargs)
369{
370  GType type;
371  int i;
372  double d;
373  char *s;
374
375  g_return_if_fail (structure != NULL);
376
377  while (fieldname) {
378    GstStructureField field = { 0 };
379
380    field.name = g_quark_from_string (fieldname);
381
382    type = va_arg (varargs, GType);
383
384    switch (type) {
385      case G_TYPE_INT:
386        i = va_arg (varargs, int);
387
388        g_value_init (&field.value, G_TYPE_INT);
389        g_value_set_int (&field.value, i);
390        break;
391      case G_TYPE_DOUBLE:
392        d = va_arg (varargs, double);
393
394        g_value_init (&field.value, G_TYPE_DOUBLE);
395        g_value_set_double (&field.value, d);
396        break;
397      case G_TYPE_BOOLEAN:
398        i = va_arg (varargs, int);
399
400        g_value_init (&field.value, G_TYPE_BOOLEAN);
401        g_value_set_boolean (&field.value, i);
402        break;
403      case G_TYPE_STRING:
404        s = va_arg (varargs, char *);
405
406        g_value_init (&field.value, G_TYPE_STRING);
407        g_value_set_string (&field.value, s);
408        break;
409      default:
410        if (type == GST_TYPE_FOURCC) {
411          i = va_arg (varargs, int);
412
413          g_value_init (&field.value, GST_TYPE_FOURCC);
414          gst_value_set_fourcc (&field.value, i);
415        } else if (type == GST_TYPE_INT_RANGE) {
416          int min, max;
417          min = va_arg (varargs, int);
418          max = va_arg (varargs, int);
419
420          g_value_init (&field.value, GST_TYPE_INT_RANGE);
421          gst_value_set_int_range (&field.value, min, max);
422        } else if (type == GST_TYPE_DOUBLE_RANGE) {
423          double min, max;
424          min = va_arg (varargs, double);
425          max = va_arg (varargs, double);
426
427          g_value_init (&field.value, GST_TYPE_DOUBLE_RANGE);
428          gst_value_set_double_range (&field.value, min, max);
429        } else if (type == GST_TYPE_BUFFER) {
430          GstBuffer *buffer = va_arg (varargs, GstBuffer *);
431
432          g_value_init (&field.value, GST_TYPE_BUFFER);
433          g_value_set_boxed (&field.value, buffer);
434        } else if (type == GST_TYPE_FRACTION) {
435          gint n, d;
436          n = va_arg (varargs, int);
437          d = va_arg (varargs, int);
438
439          g_value_init (&field.value, GST_TYPE_FRACTION);
440          gst_value_set_fraction (&field.value, n, d);
441        } else {
442          g_critical ("unimplemented vararg field type %d\n", (int) type);
443          return;
444        }
445        break;
446    }
447
448    gst_structure_set_field (structure, &field);
449
450    fieldname = va_arg (varargs, gchar *);
451  }
452}
453
454/**
455 * gst_structure_set_field:
456 * @structure: a #GstStructure
457 * @field: the #GstStructureField to set
458 *
459 * Sets a field in the structure.  If the structure currently contains
460 * a field with the same name, it is replaced with the provided field.
461 * Otherwise, the field is added to the structure.  The field's value
462 * is not deeply copied.
463 *
464 * This function is intended mainly for internal use.  The function
465 * #gst_structure_set() is recommended instead of this one.
466 */
467static void
468gst_structure_set_field (GstStructure * structure, GstStructureField * field)
469{
470  GstStructureField *f;
471  int i;
472
473  for (i = 0; i < structure->fields->len; i++) {
474    f = GST_STRUCTURE_FIELD (structure, i);
475
476    if (f->name == field->name) {
477      g_value_unset (&f->value);
478      memcpy (f, field, sizeof (GstStructureField));
479      return;
480    }
481  }
482
483  g_array_append_val (structure->fields, *field);
484}
485
486/* FIXME: is this private ? if so remove gtk-doc
487 * gst_structure_id_get_field:
488 * @structure: a #GstStructure
489 * @field_id: the GQuark of the field to get
490 *
491 * Gets the specified field from the structure.  If there is no
492 * field with the given ID, NULL is returned.
493 *
494 * Returns: the #GstStructureField with the given ID
495 */
496static GstStructureField *
497gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
498{
499  GstStructureField *field;
500  int i;
501
502  g_return_val_if_fail (structure != NULL, NULL);
503
504  for (i = 0; i < structure->fields->len; i++) {
505    field = GST_STRUCTURE_FIELD (structure, i);
506
507    if (field->name == field_id)
508      return field;
509  }
510
511  return NULL;
512}
513
514/**
515 * gst_structure_get_field:
516 * @structure: a #GstStructure
517 * @fieldname: the name of the field to get
518 *
519 * Gets the specified field from the structure.  If there is no
520 * field with the given ID, NULL is returned.
521 *
522 * Returns: the #GstStructureField with the given name
523 */
524static GstStructureField *
525gst_structure_get_field (const GstStructure * structure,
526    const gchar * fieldname)
527{
528  g_return_val_if_fail (structure != NULL, NULL);
529  g_return_val_if_fail (fieldname != NULL, NULL);
530
531  return gst_structure_id_get_field (structure,
532      g_quark_from_string (fieldname));
533}
534
535/**
536 * gst_structure_get_value:
537 * @structure: a #GstStructure
538 * @fieldname: the name of the field to get
539 *
540 * Accessor function.
541 *
542 * Returns: the #GValue corresponding to the field with the given name.
543 */
544const GValue *
545gst_structure_get_value (const GstStructure * structure,
546    const gchar * fieldname)
547{
548  GstStructureField *field;
549
550  g_return_val_if_fail (structure != NULL, NULL);
551  g_return_val_if_fail (fieldname != NULL, NULL);
552
553  field = gst_structure_get_field (structure, fieldname);
554  if (field == NULL)
555    return NULL;
556
557  return &field->value;
558}
559
560/**
561 * gst_structure_id_get_value:
562 * @structure: a #GstStructure
563 * @field: the #GQuark of the field to get
564 *
565 * Accessor function.
566 *
567 * Returns: the #GValue corresponding to the field with the given name
568 *          identifier.
569 */
570const GValue *
571gst_structure_id_get_value (const GstStructure * structure, GQuark field)
572{
573  GstStructureField *gsfield;
574
575  g_return_val_if_fail (structure != NULL, NULL);
576
577  gsfield = gst_structure_id_get_field (structure, field);
578  if (gsfield == NULL)
579    return NULL;
580
581  return &gsfield->value;
582}
583
584/**
585 * gst_structure_remove_field:
586 * @structure: a #GstStructure
587 * @fieldname: the name of the field to remove
588 *
589 * Removes the field with the given name.  If the field with the given
590 * name does not exist, the structure is unchanged.
591 */
592void
593gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
594{
595  GstStructureField *field;
596  GQuark id;
597  int i;
598
599  g_return_if_fail (structure != NULL);
600  g_return_if_fail (fieldname != NULL);
601
602  id = g_quark_from_string (fieldname);
603
604  for (i = 0; i < structure->fields->len; i++) {
605    field = GST_STRUCTURE_FIELD (structure, i);
606
607    if (field->name == id) {
608      if (G_IS_VALUE (&field->value)) {
609        g_value_unset (&field->value);
610      }
611      structure->fields = g_array_remove_index (structure->fields, i);
612      return;
613    }
614  }
615}
616
617/**
618 * gst_structure_remove_fields:
619 * @structure: a #GstStructure
620 * @fieldname: the name of the field to remove
621 * @...: NULL-terminated list of more fieldnames to remove
622 *
623 * Removes the field with the given names. If a field does not exist, the
624 * argument is ignored.
625 */
626void
627gst_structure_remove_fields (GstStructure * structure,
628    const gchar * fieldname, ...)
629{
630  va_list varargs;
631
632  g_return_if_fail (structure != NULL);
633  g_return_if_fail (fieldname != NULL);
634
635  va_start (varargs, fieldname);
636
637  gst_structure_remove_fields_valist (structure, fieldname, varargs);
638
639  va_end (varargs);
640}
641
642/**
643 * gst_structure_remove_fields_valist:
644 * @structure: a #GstStructure
645 * @fieldname: the name of the field to remove
646 * @varargs: NULL-terminated list of more fieldnames to remove
647 *
648 * Removes the field with the given names. If a field does not exist, the
649 * argument is ignored.
650 */
651void
652gst_structure_remove_fields_valist (GstStructure * structure,
653    const gchar * fieldname, va_list varargs)
654{
655  gchar *field = (gchar *) fieldname;
656
657  g_return_if_fail (structure != NULL);
658  g_return_if_fail (fieldname != NULL);
659
660  while (field) {
661    gst_structure_remove_field (structure, field);
662    field = va_arg (varargs, char *);
663  }
664}
665
666/**
667 * gst_structure_remove_all_fields:
668 * @structure: a #GstStructure
669 *
670 * Removes all fields in a GstStructure.
671 */
672void
673gst_structure_remove_all_fields (GstStructure * structure)
674{
675  GstStructureField *field;
676  int i;
677
678  g_return_if_fail (structure != NULL);
679
680  for (i = structure->fields->len - 1; i >= 0; i--) {
681    field = GST_STRUCTURE_FIELD (structure, i);
682
683    if (G_IS_VALUE (&field->value)) {
684      g_value_unset (&field->value);
685    }
686    structure->fields = g_array_remove_index (structure->fields, i);
687  }
688}
689
690/**
691 * gst_structure_get_field_type:
692 * @structure: a #GstStructure
693 * @fieldname: the name of the field
694 *
695 * Finds the field with the given name, and returns the type of the
696 * value it contains.  If the field is not found, G_TYPE_INVALID is
697 * returned.
698 *
699 * Returns: the #GValue of the field
700 */
701GType
702gst_structure_get_field_type (const GstStructure * structure,
703    const gchar * fieldname)
704{
705  GstStructureField *field;
706
707  g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
708  g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
709
710  field = gst_structure_get_field (structure, fieldname);
711  if (field == NULL)
712    return G_TYPE_INVALID;
713
714  return G_VALUE_TYPE (&field->value);
715}
716
717/**
718 * gst_structure_n_fields:
719 * @structure: a #GstStructure
720 *
721 * Accessor function.
722 *
723 * Returns: the number of fields in the structure
724 */
725gint
726gst_structure_n_fields (const GstStructure * structure)
727{
728  g_return_val_if_fail (structure != NULL, 0);
729
730  return structure->fields->len;
731}
732
733/**
734 * gst_structure_foreach:
735 * @structure: a #GstStructure
736 * @func: a function to call for each field
737 * @user_data: private data
738 *
739 * Calls the provided function once for each field in the #GstStructure.
740 *
741 * Returns: TRUE if the supplied function returns TRUE For each of the fields,
742 * FALSE otherwise.
743 */
744gboolean
745gst_structure_foreach (GstStructure * structure,
746    GstStructureForeachFunc func, gpointer user_data)
747{
748  int i;
749  GstStructureField *field;
750  gboolean ret;
751
752  for (i = 0; i < structure->fields->len; i++) {
753    field = GST_STRUCTURE_FIELD (structure, i);
754
755    ret = func (field->name, &field->value, user_data);
756    if (!ret)
757      return FALSE;
758  }
759
760  return TRUE;
761}
762
763/**
764 * gst_structure_has_field:
765 * @structure: a #GstStructure
766 * @fieldname: the name of a field
767 *
768 * Accessor function.
769 *
770 * Returns: TRUE if the structure contains a field with the given name
771 */
772gboolean
773gst_structure_has_field (const GstStructure * structure,
774    const gchar * fieldname)
775{
776  GstStructureField *field;
777
778  g_return_val_if_fail (structure != NULL, 0);
779  g_return_val_if_fail (fieldname != NULL, 0);
780
781  field = gst_structure_get_field (structure, fieldname);
782
783  return (field != NULL);
784}
785
786/**
787 * gst_structure_has_field_typed:
788 * @structure: a #GstStructure
789 * @fieldname: the name of a field
790 * @type: the type of a value
791 *
792 * Accessor function.
793 *
794 * Returns: TRUE if the structure contains a field with the given name and type
795 */
796gboolean
797gst_structure_has_field_typed (const GstStructure * structure,
798    const gchar * fieldname, GType type)
799{
800  GstStructureField *field;
801
802  g_return_val_if_fail (structure != NULL, 0);
803  g_return_val_if_fail (fieldname != NULL, 0);
804
805  field = gst_structure_get_field (structure, fieldname);
806  if (field == NULL)
807    return FALSE;
808
809  return (G_VALUE_TYPE (&field->value) == type);
810}
811
812
813/* utility functions */
814
815/**
816 * gst_structure_get_boolean:
817 * @structure: a #GstStructure
818 * @fieldname: the name of a field
819 * @value: a pointer to a #gboolean to set
820 *
821 * Sets the boolean pointed to by @value corresponding to the value of the
822 * given field.  Caller is responsible for making sure the field exists
823 * and has the correct type.
824 *
825 * Returns: TRUE if the value could be set correctly
826 */
827gboolean
828gst_structure_get_boolean (const GstStructure * structure,
829    const gchar * fieldname, gboolean * value)
830{
831  GstStructureField *field;
832
833  g_return_val_if_fail (structure != NULL, FALSE);
834  g_return_val_if_fail (fieldname != NULL, FALSE);
835
836  field = gst_structure_get_field (structure, fieldname);
837
838  if (field == NULL)
839    return FALSE;
840  if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
841    return FALSE;
842
843  *value = g_value_get_boolean (&field->value);
844
845  return TRUE;
846}
847
848/**
849 * gst_structure_get_int:
850 * @structure: a #GstStructure
851 * @fieldname: the name of a field
852 * @value: a pointer to an int to set
853 *
854 * Sets the int pointed to by @value corresponding to the value of the
855 * given field.  Caller is responsible for making sure the field exists
856 * and has the correct type.
857 *
858 * Returns: TRUE if the value could be set correctly
859 */
860gboolean
861gst_structure_get_int (const GstStructure * structure,
862    const gchar * fieldname, gint * value)
863{
864  GstStructureField *field;
865
866  g_return_val_if_fail (structure != NULL, FALSE);
867  g_return_val_if_fail (fieldname != NULL, FALSE);
868  g_return_val_if_fail (value != NULL, FALSE);
869
870  field = gst_structure_get_field (structure, fieldname);
871
872  if (field == NULL)
873    return FALSE;
874  if (!G_VALUE_HOLDS_INT (&field->value))
875    return FALSE;
876
877  *value = g_value_get_int (&field->value);
878
879  return TRUE;
880}
881
882/**
883 * gst_structure_get_fourcc:
884 * @structure: a #GstStructure
885 * @fieldname: the name of a field
886 * @value: a pointer to a #GstFourcc to set
887 *
888 * Sets the #GstFourcc pointed to by @value corresponding to the value of the
889 * given field.  Caller is responsible for making sure the field exists
890 * and has the correct type.
891 *
892 * Returns: TRUE if the value could be set correctly
893 */
894gboolean
895gst_structure_get_fourcc (const GstStructure * structure,
896    const gchar * fieldname, guint32 * value)
897{
898  GstStructureField *field;
899
900  g_return_val_if_fail (structure != NULL, FALSE);
901  g_return_val_if_fail (fieldname != NULL, FALSE);
902  g_return_val_if_fail (value != NULL, FALSE);
903
904  field = gst_structure_get_field (structure, fieldname);
905
906  if (field == NULL)
907    return FALSE;
908  if (!GST_VALUE_HOLDS_FOURCC (&field->value))
909    return FALSE;
910
911  *value = gst_value_get_fourcc (&field->value);
912
913  return TRUE;
914}
915
916/**
917 * gst_structure_get_double:
918 * @structure: a #GstStructure
919 * @fieldname: the name of a field
920 * @value: a pointer to a #GstFourcc to set
921 *
922 * Sets the double pointed to by @value corresponding to the value of the
923 * given field.  Caller is responsible for making sure the field exists
924 * and has the correct type.
925 *
926 * Returns: TRUE if the value could be set correctly
927 */
928gboolean
929gst_structure_get_double (const GstStructure * structure,
930    const gchar * fieldname, gdouble * value)
931{
932  GstStructureField *field;
933
934  g_return_val_if_fail (structure != NULL, FALSE);
935  g_return_val_if_fail (fieldname != NULL, FALSE);
936  g_return_val_if_fail (value != NULL, FALSE);
937
938  field = gst_structure_get_field (structure, fieldname);
939
940  if (field == NULL)
941    return FALSE;
942  if (!G_VALUE_HOLDS_DOUBLE (&field->value))
943    return FALSE;
944
945  *value = g_value_get_double (&field->value);
946
947  return TRUE;
948}
949
950/**
951 * gst_structure_get_string:
952 * @structure: a #GstStructure
953 * @fieldname: the name of a field
954 *
955 * Finds the field corresponding to @fieldname, and returns the string
956 * contained in the field's value.  Caller is responsible for making
957 * sure the field exists and has the correct type.
958 *
959 * The string should not be modified, and remains valid until the next
960 * call to a gst_structure_*() function with the given structure.
961 *
962 * Returns: a pointer to the string
963 */
964const gchar *
965gst_structure_get_string (const GstStructure * structure,
966    const gchar * fieldname)
967{
968  GstStructureField *field;
969
970  g_return_val_if_fail (structure != NULL, NULL);
971  g_return_val_if_fail (fieldname != NULL, NULL);
972
973  field = gst_structure_get_field (structure, fieldname);
974
975  if (field == NULL)
976    return NULL;
977  if (!G_VALUE_HOLDS_STRING (&field->value))
978    return NULL;
979
980  return g_value_get_string (&field->value);
981}
982
983typedef struct _GstStructureAbbreviation
984{
985  char *type_name;
986  GType type;
987}
988GstStructureAbbreviation;
989
990static GstStructureAbbreviation *
991gst_structure_get_abbrs (gint * n_abbrs)
992{
993  static GstStructureAbbreviation *abbrs = NULL;
994  static gint num = 0;
995
996  if (abbrs == NULL) {
997    /* dynamically generate the array */
998    GstStructureAbbreviation dyn_abbrs[] = {
999      {"int", G_TYPE_INT}
1000      ,
1001      {"i", G_TYPE_INT}
1002      ,
1003      {"float", G_TYPE_FLOAT}
1004      ,
1005      {"f", G_TYPE_FLOAT}
1006      ,
1007      {"double", G_TYPE_DOUBLE}
1008      ,
1009      {"d", G_TYPE_DOUBLE}
1010      ,
1011      {"buffer", GST_TYPE_BUFFER}
1012      ,
1013      {"fourcc", GST_TYPE_FOURCC}
1014      ,
1015      {"4", GST_TYPE_FOURCC}
1016      ,
1017      {"fraction", GST_TYPE_FRACTION}
1018      ,
1019      {"boolean", G_TYPE_BOOLEAN}
1020      ,
1021      {"bool", G_TYPE_BOOLEAN}
1022      ,
1023      {"b", G_TYPE_BOOLEAN}
1024      ,
1025      {"string", G_TYPE_STRING}
1026      ,
1027      {"str", G_TYPE_STRING}
1028      ,
1029      {"s", G_TYPE_STRING}
1030    };
1031    num = G_N_ELEMENTS (dyn_abbrs);
1032    /* permanently allocate and copy the array now */
1033    abbrs = g_new0 (GstStructureAbbreviation, num);
1034    memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num);
1035  }
1036  *n_abbrs = num;
1037
1038  return abbrs;
1039}
1040
1041static GType
1042gst_structure_from_abbr (const char *type_name)
1043{
1044  int i;
1045  GstStructureAbbreviation *abbrs;
1046  gint n_abbrs;
1047
1048  g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1049
1050  abbrs = gst_structure_get_abbrs (&n_abbrs);
1051
1052  for (i = 0; i < n_abbrs; i++) {
1053    if (strcmp (type_name, abbrs[i].type_name) == 0) {
1054      return abbrs[i].type;
1055    }
1056  }
1057
1058  /* this is the fallback */
1059  return g_type_from_name (type_name);
1060}
1061
1062static const char *
1063gst_structure_to_abbr (GType type)
1064{
1065  int i;
1066  GstStructureAbbreviation *abbrs;
1067  gint n_abbrs;
1068
1069  g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1070
1071  abbrs = gst_structure_get_abbrs (&n_abbrs);
1072
1073  for (i = 0; i < n_abbrs; i++) {
1074    if (type == abbrs[i].type) {
1075      return abbrs[i].type_name;
1076    }
1077  }
1078
1079  return g_type_name (type);
1080}
1081
1082static GType
1083gst_structure_value_get_generic_type (GValue * val)
1084{
1085  if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1086      || G_VALUE_TYPE (val) == GST_TYPE_FIXED_LIST) {
1087    GArray *array = g_value_peek_pointer (val);
1088
1089    if (array->len > 0) {
1090      GValue *value = &g_array_index (array, GValue, 0);
1091
1092      return gst_structure_value_get_generic_type (value);
1093    } else {
1094      return G_TYPE_INT;
1095    }
1096  } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1097    return G_TYPE_INT;
1098  } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1099    return G_TYPE_DOUBLE;
1100  }
1101  return G_VALUE_TYPE (val);
1102}
1103
1104#define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1105      ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1106      ((c) == '.'))
1107
1108/**
1109 * gst_structure_to_string:
1110 * @structure: a #GstStructure
1111 *
1112 * Converts @structure to a human-readable representation.
1113 *
1114 * Returns: a pointer to string allocated by g_malloc()
1115 */
1116gchar *
1117gst_structure_to_string (const GstStructure * structure)
1118{
1119  GstStructureField *field;
1120  GString *s;
1121  int i;
1122
1123  /* NOTE:  This function is potentially called by the debug system,
1124   * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1125   * should be careful to avoid recursion.  This includes any functions
1126   * called by gst_structure_to_string.  In particular, calls should
1127   * not use the GST_PTR_FORMAT extension.  */
1128
1129  g_return_val_if_fail (structure != NULL, NULL);
1130
1131  s = g_string_new ("");
1132  /* FIXME this string may need to be escaped */
1133  g_string_append_printf (s, "%s", g_quark_to_string (structure->name));
1134  for (i = 0; i < structure->fields->len; i++) {
1135    char *t;
1136    GType type;
1137
1138    field = GST_STRUCTURE_FIELD (structure, i);
1139
1140    t = gst_value_serialize (&field->value);
1141    type = gst_structure_value_get_generic_type (&field->value);
1142
1143    g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name),
1144        gst_structure_to_abbr (type), t);
1145    g_free (t);
1146  }
1147  return g_string_free (s, FALSE);
1148}
1149
1150/*
1151 * r will still point to the string. if end == next, the string will not be
1152 * null-terminated. In all other cases it will be.
1153 * end = pointer to char behind end of string, next = pointer to start of
1154 * unread data.
1155 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1156 */
1157static gboolean
1158gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1159{
1160  gchar *w;
1161
1162  if (*s == 0)
1163    return FALSE;
1164
1165  if (*s != '"') {
1166    int ret;
1167
1168    ret = gst_structure_parse_simple_string (s, end);
1169    *next = *end;
1170
1171    return ret;
1172  }
1173
1174  w = s;
1175  s++;
1176  while (*s != '"') {
1177    if (*s == 0)
1178      return FALSE;
1179
1180    if (*s == '\\') {
1181      s++;
1182    }
1183
1184    *w = *s;
1185    w++;
1186    s++;
1187  }
1188  s++;
1189
1190  *end = w;
1191  *next = s;
1192
1193  return TRUE;
1194}
1195
1196static gboolean
1197gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1198    GType type)
1199{
1200  GValue value1 = { 0 };
1201  GValue value2 = { 0 };
1202  GType range_type;
1203  gboolean ret;
1204
1205
1206  if (*s != '[')
1207    return FALSE;
1208  s++;
1209
1210  ret = gst_structure_parse_value (s, &s, &value1, type);
1211  if (ret == FALSE)
1212    return FALSE;
1213
1214  while (g_ascii_isspace (*s))
1215    s++;
1216
1217  if (*s != ',')
1218    return FALSE;
1219  s++;
1220
1221  while (g_ascii_isspace (*s))
1222    s++;
1223
1224  ret = gst_structure_parse_value (s, &s, &value2, type);
1225  if (ret == FALSE)
1226    return FALSE;
1227
1228  while (g_ascii_isspace (*s))
1229    s++;
1230
1231  if (*s != ']')
1232    return FALSE;
1233  s++;
1234
1235  if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1236    return FALSE;
1237
1238  if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1239    range_type = GST_TYPE_DOUBLE_RANGE;
1240  } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1241    range_type = GST_TYPE_INT_RANGE;
1242  } else {
1243    return FALSE;
1244  }
1245
1246  g_value_init (value, range_type);
1247  if (range_type == GST_TYPE_DOUBLE_RANGE) {
1248    gst_value_set_double_range (value, g_value_get_double (&value1),
1249        g_value_get_double (&value2));
1250  } else {
1251    gst_value_set_int_range (value, g_value_get_int (&value1),
1252        g_value_get_int (&value2));
1253  }
1254
1255  *after = s;
1256  return TRUE;
1257}
1258
1259static gboolean
1260gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1261    GType type, GType list_type, char begin, char end)
1262{
1263  GValue list_value = { 0 };
1264  gboolean ret;
1265  GArray *array;
1266
1267  g_value_init (value, list_type);
1268  array = g_value_peek_pointer (value);
1269
1270  if (*s != begin)
1271    return FALSE;
1272  s++;
1273
1274  while (g_ascii_isspace (*s))
1275    s++;
1276  if (*s == end) {
1277    s++;
1278    *after = s;
1279    return TRUE;
1280  }
1281
1282  ret = gst_structure_parse_value (s, &s, &list_value, type);
1283  if (ret == FALSE)
1284    return FALSE;
1285
1286  g_array_append_val (array, list_value);
1287
1288  while (g_ascii_isspace (*s))
1289    s++;
1290
1291  while (*s != end) {
1292    if (*s != ',')
1293      return FALSE;
1294    s++;
1295
1296    while (g_ascii_isspace (*s))
1297      s++;
1298
1299    memset (&list_value, 0, sizeof (list_value));
1300    ret = gst_structure_parse_value (s, &s, &list_value, type);
1301    if (ret == FALSE)
1302      return FALSE;
1303
1304    g_array_append_val (array, list_value);
1305    while (g_ascii_isspace (*s))
1306      s++;
1307  }
1308
1309  s++;
1310
1311  *after = s;
1312  return TRUE;
1313}
1314
1315static gboolean
1316gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1317{
1318  return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1319      '{', '}');
1320}
1321
1322static gboolean
1323gst_structure_parse_fixed_list (gchar * s, gchar ** after, GValue * value,
1324    GType type)
1325{
1326  return gst_structure_parse_any_list (s, after, value, type,
1327      GST_TYPE_FIXED_LIST, '<', '>');
1328}
1329
1330static gboolean
1331gst_structure_parse_simple_string (gchar * str, gchar ** end)
1332{
1333  char *s = str;
1334
1335  while (GST_ASCII_IS_STRING (*s)) {
1336    s++;
1337  }
1338
1339  *end = s;
1340
1341  return (s != str);
1342}
1343
1344static gboolean
1345gst_structure_parse_field (gchar * str,
1346    gchar ** after, GstStructureField * field)
1347{
1348  gchar *name;
1349  gchar *name_end;
1350  gchar *s;
1351  gchar c;
1352
1353  s = str;
1354
1355  while (g_ascii_isspace (*s))
1356    s++;
1357  name = s;
1358  if (!gst_structure_parse_simple_string (s, &name_end))
1359    return FALSE;
1360
1361  s = name_end;
1362  while (g_ascii_isspace (*s))
1363    s++;
1364
1365  if (*s != '=')
1366    return FALSE;
1367  s++;
1368
1369  c = *name_end;
1370  *name_end = 0;
1371  field->name = g_quark_from_string (name);
1372  *name_end = c;
1373
1374  if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1375    return FALSE;
1376
1377  *after = s;
1378  return TRUE;
1379}
1380
1381static gboolean
1382gst_structure_parse_value (gchar * str,
1383    gchar ** after, GValue * value, GType default_type)
1384{
1385  gchar *type_name;
1386  gchar *type_end;
1387  gchar *value_s;
1388  gchar *value_end;
1389  gchar *s;
1390  gchar c;
1391  int ret = 0;
1392  GType type = default_type;
1393
1394
1395  s = str;
1396  while (g_ascii_isspace (*s))
1397    s++;
1398
1399  type_name = NULL;
1400  if (*s == '(') {
1401    type = G_TYPE_INVALID;
1402
1403    s++;
1404    while (g_ascii_isspace (*s))
1405      s++;
1406    type_name = s;
1407    if (!gst_structure_parse_simple_string (s, &type_end))
1408      return FALSE;
1409    s = type_end;
1410    while (g_ascii_isspace (*s))
1411      s++;
1412    if (*s != ')')
1413      return FALSE;
1414    s++;
1415    while (g_ascii_isspace (*s))
1416      s++;
1417
1418    c = *type_end;
1419    *type_end = 0;
1420    type = gst_structure_from_abbr (type_name);
1421    *type_end = c;
1422
1423    if (type == G_TYPE_INVALID)
1424      return FALSE;
1425  }
1426
1427  while (g_ascii_isspace (*s))
1428    s++;
1429  if (*s == '[') {
1430    ret = gst_structure_parse_range (s, &s, value, type);
1431  } else if (*s == '{') {
1432    ret = gst_structure_parse_list (s, &s, value, type);
1433  } else if (*s == '<') {
1434    ret = gst_structure_parse_fixed_list (s, &s, value, type);
1435  } else {
1436    value_s = s;
1437    if (!gst_structure_parse_string (s, &value_end, &s))
1438      return FALSE;
1439
1440    c = *value_end;
1441    *value_end = 0;
1442    if (type == G_TYPE_INVALID) {
1443      GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1444      int i;
1445
1446      for (i = 0; i < 3; i++) {
1447        g_value_init (value, try_types[i]);
1448        ret = gst_value_deserialize (value, value_s);
1449        if (ret)
1450          break;
1451        g_value_unset (value);
1452      }
1453    } else {
1454      g_value_init (value, type);
1455
1456      ret = gst_value_deserialize (value, value_s);
1457    }
1458    *value_end = c;
1459  }
1460
1461  *after = s;
1462
1463  return ret;
1464}
1465
1466/**
1467 * gst_structure_from_string:
1468 * @string: a string representation of a #GstStructure.
1469 * @end: FIXME, deduce from code
1470 *
1471 * Creates a #GstStructure from a string representation.
1472 *
1473 * Returns: a new #GstStructure
1474 */
1475GstStructure *
1476gst_structure_from_string (const gchar * string, gchar ** end)
1477{
1478  char *name;
1479  char *copy;
1480  char *w;
1481  char *r;
1482  char save;
1483  GstStructure *structure = NULL;
1484  GstStructureField field = { 0 };
1485
1486  g_return_val_if_fail (string != NULL, NULL);
1487
1488  copy = g_strdup (string);
1489  r = copy;
1490
1491  name = r;
1492  if (!gst_structure_parse_string (r, &w, &r))
1493    goto error;
1494
1495  while (g_ascii_isspace (*r))
1496    r++;
1497  if (*r != 0 && *r != ';' && *r != ',')
1498    goto error;
1499
1500  save = *w;
1501  *w = 0;
1502  structure = gst_structure_empty_new (name);
1503  *w = save;
1504
1505  while (*r && (*r != ';')) {
1506    if (*r != ',')
1507      goto error;
1508    r++;
1509    while (*r && g_ascii_isspace (*r))
1510      r++;
1511
1512    memset (&field, 0, sizeof (field));
1513    if (!gst_structure_parse_field (r, &r, &field))
1514      goto error;
1515    gst_structure_set_field (structure, &field);
1516    while (*r && g_ascii_isspace (*r))
1517      r++;
1518  }
1519
1520  if (end)
1521    *end = (char *) string + (r - copy);
1522
1523  g_free (copy);
1524  return structure;
1525
1526error:
1527  if (structure)
1528    gst_structure_free (structure);
1529  g_free (copy);
1530  return NULL;
1531}
1532
1533static void
1534gst_structure_transform_to_string (const GValue * src_value,
1535    GValue * dest_value)
1536{
1537  g_return_if_fail (src_value != NULL);
1538  g_return_if_fail (dest_value != NULL);
1539
1540  dest_value->data[0].v_pointer =
1541      gst_structure_to_string (src_value->data[0].v_pointer);
1542}
1543
1544static GstStructure *
1545gst_structure_copy_conditional (const GstStructure * structure)
1546{
1547  if (structure)
1548    return gst_structure_copy (structure);
1549  return NULL;
1550}
Note: See TracBrowser for help on using the repository browser.