gst/: Aplied part of patch #157127: Cleanup of issues reported by sparse.
[platform/upstream/gstreamer.git] / gst / gstutils.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstutils.c: Utility functions: gtk_get_property stuff, etc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "gst_private.h"
27 #include "gstutils.h"
28 #include "gsturitype.h"
29 #include "gstinfo.h"
30
31 /**
32  * gst_util_dump_mem:
33  * @mem: a pointer to the memory to dump
34  * @size: the size of the memory block to dump
35  *
36  * Dumps the memory block into a hex representation. Useful for debugging.
37  */
38 void
39 gst_util_dump_mem (const guchar * mem, guint size)
40 {
41   guint i, j;
42   GString *string = g_string_sized_new (50);
43   GString *chars = g_string_sized_new (18);
44
45   i = j = 0;
46   while (i < size) {
47     if (g_ascii_isprint (mem[i]))
48       g_string_append_printf (chars, "%c", mem[i]);
49     else
50       g_string_append_printf (chars, ".");
51
52     g_string_append_printf (string, "%02x ", mem[i]);
53
54     j++;
55     i++;
56
57     if (j == 16 || i == size) {
58       g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
59           string->str, chars->str);
60       g_string_set_size (string, 0);
61       g_string_set_size (chars, 0);
62       j = 0;
63     }
64   }
65   g_string_free (string, TRUE);
66   g_string_free (chars, TRUE);
67 }
68
69
70 /**
71  * gst_util_set_value_from_string:
72  * @value: the value to set
73  * @value_str: the string to get the value from
74  *
75  * Converts the string to the type of the value and
76  * sets the value with it.
77  */
78 void
79 gst_util_set_value_from_string (GValue * value, const gchar * value_str)
80 {
81
82   g_return_if_fail (value != NULL);
83   g_return_if_fail (value_str != NULL);
84
85   GST_CAT_DEBUG (GST_CAT_PARAMS, "parsing '%s' to type %s", value_str,
86       g_type_name (G_VALUE_TYPE (value)));
87
88   switch (G_VALUE_TYPE (value)) {
89     case G_TYPE_STRING:
90       g_value_set_string (value, g_strdup (value_str));
91       break;
92     case G_TYPE_ENUM:
93     case G_TYPE_INT:{
94       gint i;
95
96       sscanf (value_str, "%d", &i);
97       g_value_set_int (value, i);
98       break;
99     }
100     case G_TYPE_UINT:{
101       guint i;
102
103       sscanf (value_str, "%u", &i);
104       g_value_set_uint (value, i);
105       break;
106     }
107     case G_TYPE_LONG:{
108       glong i;
109
110       sscanf (value_str, "%ld", &i);
111       g_value_set_long (value, i);
112       break;
113     }
114     case G_TYPE_ULONG:{
115       gulong i;
116
117       sscanf (value_str, "%lu", &i);
118       g_value_set_ulong (value, i);
119       break;
120     }
121     case G_TYPE_BOOLEAN:{
122       gboolean i = FALSE;
123
124       if (!strncmp ("true", value_str, 4))
125         i = TRUE;
126       g_value_set_boolean (value, i);
127       break;
128     }
129     case G_TYPE_CHAR:{
130       gchar i;
131
132       sscanf (value_str, "%c", &i);
133       g_value_set_char (value, i);
134       break;
135     }
136     case G_TYPE_UCHAR:{
137       guchar i;
138
139       sscanf (value_str, "%c", &i);
140       g_value_set_uchar (value, i);
141       break;
142     }
143     case G_TYPE_FLOAT:{
144       gfloat i;
145
146       sscanf (value_str, "%f", &i);
147       g_value_set_float (value, i);
148       break;
149     }
150     case G_TYPE_DOUBLE:{
151       gfloat i;
152
153       sscanf (value_str, "%g", &i);
154       g_value_set_double (value, (gdouble) i);
155       break;
156     }
157     default:
158       break;
159   }
160 }
161
162 /**
163  * gst_util_set_object_arg:
164  * @object: the object to set the argument of
165  * @name: the name of the argument to set
166  * @value: the string value to set
167  *
168  * Convertes the string value to the type of the objects argument and
169  * sets the argument with it.
170  */
171 void
172 gst_util_set_object_arg (GObject * object, const gchar * name,
173     const gchar * value)
174 {
175   if (name && value) {
176     GParamSpec *paramspec;
177
178     paramspec =
179         g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
180
181     if (!paramspec) {
182       return;
183     }
184
185     GST_DEBUG ("paramspec->flags is %d, paramspec->value_type is %d",
186         paramspec->flags, (gint) paramspec->value_type);
187
188     if (paramspec->flags & G_PARAM_WRITABLE) {
189       switch (paramspec->value_type) {
190         case G_TYPE_STRING:
191           g_object_set (G_OBJECT (object), name, value, NULL);
192           break;
193         case G_TYPE_ENUM:
194         case G_TYPE_INT:{
195           gint i;
196
197           sscanf (value, "%d", &i);
198           g_object_set (G_OBJECT (object), name, i, NULL);
199           break;
200         }
201         case G_TYPE_UINT:{
202           guint i;
203
204           sscanf (value, "%u", &i);
205           g_object_set (G_OBJECT (object), name, i, NULL);
206           break;
207         }
208         case G_TYPE_LONG:{
209           glong i;
210
211           sscanf (value, "%ld", &i);
212           g_object_set (G_OBJECT (object), name, i, NULL);
213           break;
214         }
215         case G_TYPE_ULONG:{
216           gulong i;
217
218           sscanf (value, "%lu", &i);
219           g_object_set (G_OBJECT (object), name, i, NULL);
220           break;
221         }
222         case G_TYPE_BOOLEAN:{
223           gboolean i = FALSE;
224
225           if (!g_ascii_strncasecmp ("true", value, 4))
226             i = TRUE;
227           g_object_set (G_OBJECT (object), name, i, NULL);
228           break;
229         }
230         case G_TYPE_CHAR:{
231           gchar i;
232
233           sscanf (value, "%c", &i);
234           g_object_set (G_OBJECT (object), name, i, NULL);
235           break;
236         }
237         case G_TYPE_UCHAR:{
238           guchar i;
239
240           sscanf (value, "%c", &i);
241           g_object_set (G_OBJECT (object), name, i, NULL);
242           break;
243         }
244         case G_TYPE_FLOAT:{
245           gfloat i;
246
247           sscanf (value, "%f", &i);
248           g_object_set (G_OBJECT (object), name, i, NULL);
249           break;
250         }
251         case G_TYPE_DOUBLE:{
252           gfloat i;
253
254           sscanf (value, "%g", &i);
255           g_object_set (G_OBJECT (object), name, (gdouble) i, NULL);
256           break;
257         }
258         default:
259           if (G_IS_PARAM_SPEC_ENUM (paramspec)) {
260             gint i;
261
262             sscanf (value, "%d", &i);
263             g_object_set (G_OBJECT (object), name, i, NULL);
264           } else if (paramspec->value_type == GST_TYPE_URI) {
265             g_object_set (G_OBJECT (object), name, value, NULL);
266           }
267           break;
268       }
269     }
270   }
271 }
272
273 /* -----------------------------------------------------
274  *
275  *  The following code will be moved out of the main
276  * gstreamer library someday.
277  */
278
279 #include "gstpad.h"
280
281 static void
282 string_append_indent (GString * str, gint count)
283 {
284   gint xx;
285
286   for (xx = 0; xx < count; xx++)
287     g_string_append_c (str, ' ');
288 }
289
290 /**
291  * gst_print_pad_caps:
292  * @buf: the buffer to print the caps in
293  * @indent: initial indentation
294  * @pad: the pad to print the caps from
295  *
296  * Write the pad capabilities in a human readable format into
297  * the given GString.
298  */
299 void
300 gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
301 {
302   GstRealPad *realpad;
303   GstCaps *caps;
304
305   realpad = GST_PAD_REALIZE (pad);
306   caps = realpad->caps;
307
308   if (!caps) {
309     string_append_indent (buf, indent);
310     g_string_printf (buf, "%s:%s has no capabilities",
311         GST_DEBUG_PAD_NAME (pad));
312   } else {
313     char *s;
314
315     s = gst_caps_to_string (caps);
316     g_string_append (buf, s);
317     g_free (s);
318   }
319 }
320
321 /**
322  * gst_print_element_args:
323  * @buf: the buffer to print the args in
324  * @indent: initial indentation
325  * @element: the element to print the args of
326  *
327  * Print the element argument in a human readable format in the given
328  * GString.
329  */
330 void
331 gst_print_element_args (GString * buf, gint indent, GstElement * element)
332 {
333   guint width;
334   GValue value = { 0, };        /* the important thing is that value.type = 0 */
335   gchar *str = NULL;
336   GParamSpec *spec, **specs, **walk;
337
338   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), NULL);
339
340   width = 0;
341   for (walk = specs; *walk; walk++) {
342     spec = *walk;
343     if (width < strlen (spec->name))
344       width = strlen (spec->name);
345   }
346
347   for (walk = specs; *walk; walk++) {
348     spec = *walk;
349
350     if (spec->flags & G_PARAM_READABLE) {
351       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
352       g_object_get_property (G_OBJECT (element), spec->name, &value);
353       str = g_strdup_value_contents (&value);
354       g_value_unset (&value);
355     } else {
356       str = g_strdup ("Parameter not readable.");
357     }
358
359     string_append_indent (buf, indent);
360     g_string_append (buf, spec->name);
361     string_append_indent (buf, 2 + width - strlen (spec->name));
362     g_string_append (buf, str);
363     g_string_append_c (buf, '\n');
364
365     g_free (str);
366   }
367
368   g_free (specs);
369 }