const fix
[platform/upstream/glib.git] / gobject / gvaluetypes.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include        "gvaluetypes.h"
20
21 #include        "gvaluecollector.h"
22 #include        <string.h>
23
24
25 /* --- value functions --- */
26 static void
27 value_long0_init (GValue *value)
28 {
29   value->data[0].v_long = 0;
30 }
31
32 static void
33 value_long0_copy (const GValue *src_value,
34                   GValue       *dest_value)
35 {
36   dest_value->data[0].v_long = src_value->data[0].v_long;
37 }
38
39 static gchar*
40 value_char_lcopy_value (const GValue *value,
41                         guint         nth_value,
42                         GType        *collect_type,
43                         GTypeCValue  *collect_value)
44 {
45   gint8 *int8_p = collect_value->v_pointer;
46   
47   if (!int8_p)
48     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
49   
50   *int8_p = value->data[0].v_int;
51   
52   *collect_type = 0;
53   return NULL;
54 }
55
56 static gchar*
57 value_boolean_lcopy_value (const GValue *value,
58                            guint         nth_value,
59                            GType        *collect_type,
60                            GTypeCValue  *collect_value)
61 {
62   gboolean *bool_p = collect_value->v_pointer;
63   
64   if (!bool_p)
65     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
66   
67   *bool_p = value->data[0].v_int;
68   
69   *collect_type = 0;
70   return NULL;
71 }
72
73 static gchar*
74 value_int_collect_value (GValue      *value,
75                          guint        nth_value,
76                          GType       *collect_type,
77                          GTypeCValue *collect_value)
78 {
79   value->data[0].v_int = collect_value->v_int;
80   
81   *collect_type = 0;
82   return NULL;
83 }
84
85 static gchar*
86 value_int_lcopy_value (const GValue *value,
87                        guint         nth_value,
88                        GType        *collect_type,
89                        GTypeCValue  *collect_value)
90 {
91   gint *int_p = collect_value->v_pointer;
92   
93   if (!int_p)
94     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
95   
96   *int_p = value->data[0].v_int;
97   
98   *collect_type = 0;
99   return NULL;
100 }
101
102 static gchar*
103 value_long_collect_value (GValue      *value,
104                           guint        nth_value,
105                           GType       *collect_type,
106                           GTypeCValue *collect_value)
107 {
108   value->data[0].v_long = collect_value->v_long;
109   
110   *collect_type = 0;
111   return NULL;
112 }
113
114 static gchar*
115 value_long_lcopy_value (const GValue *value,
116                         guint         nth_value,
117                         GType        *collect_type,
118                         GTypeCValue  *collect_value)
119 {
120   glong *long_p = collect_value->v_pointer;
121   
122   if (!long_p)
123     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
124   
125   *long_p = value->data[0].v_long;
126   
127   *collect_type = 0;
128   return NULL;
129 }
130
131 static void
132 value_float_init (GValue *value)
133 {
134   value->data[0].v_float = 0.0;
135 }
136
137 static void
138 value_float_copy (const GValue *src_value,
139                   GValue       *dest_value)
140 {
141   dest_value->data[0].v_float = src_value->data[0].v_float;
142 }
143
144 static gchar*
145 value_float_collect_value (GValue      *value,
146                            guint        nth_value,
147                            GType       *collect_type,
148                            GTypeCValue *collect_value)
149 {
150   value->data[0].v_float = collect_value->v_double;
151   
152   *collect_type = 0;
153   return NULL;
154 }
155
156 static gchar*
157 value_float_lcopy_value (const GValue *value,
158                          guint         nth_value,
159                          GType        *collect_type,
160                          GTypeCValue  *collect_value)
161 {
162   gfloat *float_p = collect_value->v_pointer;
163   
164   if (!float_p)
165     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
166   
167   *float_p = value->data[0].v_float;
168   
169   *collect_type = 0;
170   return NULL;
171 }
172
173 static void
174 value_double_init (GValue *value)
175 {
176   value->data[0].v_double = 0.0;
177 }
178
179 static void
180 value_double_copy (const GValue *src_value,
181                    GValue       *dest_value)
182 {
183   dest_value->data[0].v_double = src_value->data[0].v_double;
184 }
185
186 static gchar*
187 value_double_collect_value (GValue      *value,
188                             guint        nth_value,
189                             GType       *collect_type,
190                             GTypeCValue *collect_value)
191 {
192   value->data[0].v_double = collect_value->v_double;
193   
194   *collect_type = 0;
195   return NULL;
196 }
197
198 static gchar*
199 value_double_lcopy_value (const GValue *value,
200                           guint         nth_value,
201                           GType        *collect_type,
202                           GTypeCValue  *collect_value)
203 {
204   gdouble *double_p = collect_value->v_pointer;
205   
206   if (!double_p)
207     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
208   
209   *double_p = value->data[0].v_double;
210   
211   *collect_type = 0;
212   return NULL;
213 }
214
215 static void
216 value_string_init (GValue *value)
217 {
218   value->data[0].v_pointer = NULL;
219 }
220
221 static void
222 value_string_free_value (GValue *value)
223 {
224   if (!(value->data[1].v_uint & G_VALUE_STATIC_TAG))
225     g_free (value->data[0].v_pointer);
226 }
227
228 static void
229 value_string_copy_value (const GValue *src_value,
230                          GValue       *dest_value)
231 {
232   dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
233 }
234
235 static gchar*
236 value_string_collect_value (GValue      *value,
237                             guint        nth_value,
238                             GType       *collect_type,
239                             GTypeCValue *collect_value)
240 {
241   value->data[0].v_pointer = g_strdup (collect_value->v_pointer);
242   
243   *collect_type = 0;
244   return NULL;
245 }
246
247 static gchar*
248 value_string_lcopy_value (const GValue *value,
249                           guint         nth_value,
250                           GType        *collect_type,
251                           GTypeCValue  *collect_value)
252 {
253   gchar **string_p = collect_value->v_pointer;
254   
255   if (!string_p)
256     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
257   
258   *string_p = g_strdup (value->data[0].v_pointer);
259   
260   *collect_type = 0;
261   return NULL;
262 }
263
264 static void
265 value_pointer_init (GValue *value)
266 {
267   value->data[0].v_pointer = 0;
268 }
269
270 static void
271 value_pointer_copy (const GValue *src_value,
272                     GValue       *dest_value)
273 {
274   dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
275 }
276
277 static gpointer
278 value_pointer_peek_pointer (const GValue *value)
279 {
280   return value->data[0].v_pointer;
281 }
282
283 static gchar*
284 value_pointer_collect_value (GValue      *value,
285                              guint        nth_value,
286                              GType       *collect_type,
287                              GTypeCValue *collect_value)
288 {
289   value->data[0].v_pointer = collect_value->v_pointer;
290
291   *collect_type = 0;
292   return NULL;
293 }
294
295 static gchar*
296 value_pointer_lcopy_value (const GValue *value,
297                            guint         nth_value,
298                            GType        *collect_type,
299                            GTypeCValue  *collect_value)
300 {
301   gpointer *pointer_p = collect_value->v_pointer;
302
303   if (!pointer_p)
304     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
305
306   *pointer_p = value->data[0].v_pointer;
307
308   *collect_type = 0;
309   return NULL;
310 }
311
312
313 /* --- type initialization --- */
314 void
315 g_value_types_init (void)  /* sync with gtype.c */
316 {
317   GTypeInfo info = {
318     0,                          /* class_size */
319     NULL,                       /* base_init */
320     NULL,                       /* base_destroy */
321     NULL,                       /* class_init */
322     NULL,                       /* class_destroy */
323     NULL,                       /* class_data */
324     0,                          /* instance_size */
325     0,                          /* n_preallocs */
326     NULL,                       /* instance_init */
327     NULL,                       /* value_table */
328   };
329   const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
330   GType type;
331   
332   /* G_TYPE_CHAR / G_TYPE_UCHAR
333    */
334   {
335     static const GTypeValueTable value_table = {
336       value_long0_init,         /* value_init */
337       NULL,                     /* value_free */
338       value_long0_copy,         /* value_copy */
339       NULL,                     /* value_peek_pointer */
340       G_VALUE_COLLECT_INT,      /* collect_type */
341       value_int_collect_value,  /* collect_value */
342       G_VALUE_COLLECT_POINTER,  /* lcopy_type */
343       value_char_lcopy_value,   /* lcopy_value */
344     };
345     info.value_table = &value_table;
346     type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0);
347     g_assert (type == G_TYPE_CHAR);
348     type = g_type_register_fundamental (G_TYPE_UCHAR, "guchar", &info, &finfo, 0);
349     g_assert (type == G_TYPE_UCHAR);
350   }
351
352   /* G_TYPE_BOOLEAN
353    */
354   {
355     static const GTypeValueTable value_table = {
356       value_long0_init,          /* value_init */
357       NULL,                      /* value_free */
358       value_long0_copy,          /* value_copy */
359       NULL,                      /* value_peek_pointer */
360       G_VALUE_COLLECT_INT,       /* collect_type */
361       value_int_collect_value,   /* collect_value */
362       G_VALUE_COLLECT_POINTER,   /* lcopy_type */
363       value_boolean_lcopy_value, /* lcopy_value */
364     };
365     info.value_table = &value_table;
366     type = g_type_register_fundamental (G_TYPE_BOOLEAN, "gboolean", &info, &finfo, 0);
367     g_assert (type == G_TYPE_BOOLEAN);
368   }
369   
370   /* G_TYPE_INT / G_TYPE_UINT
371    */
372   {
373     static const GTypeValueTable value_table = {
374       value_long0_init,         /* value_init */
375       NULL,                     /* value_free */
376       value_long0_copy,         /* value_copy */
377       NULL,                     /* value_peek_pointer */
378       G_VALUE_COLLECT_INT,      /* collect_type */
379       value_int_collect_value,  /* collect_value */
380       G_VALUE_COLLECT_POINTER,  /* lcopy_type */
381       value_int_lcopy_value,    /* lcopy_value */
382     };
383     info.value_table = &value_table;
384     type = g_type_register_fundamental (G_TYPE_INT, "gint", &info, &finfo, 0);
385     g_assert (type == G_TYPE_INT);
386     type = g_type_register_fundamental (G_TYPE_UINT, "guint", &info, &finfo, 0);
387     g_assert (type == G_TYPE_UINT);
388   }
389
390   /* G_TYPE_LONG / G_TYPE_ULONG
391    */
392   {
393     static const GTypeValueTable value_table = {
394       value_long0_init,         /* value_init */
395       NULL,                     /* value_free */
396       value_long0_copy,         /* value_copy */
397       NULL,                     /* value_peek_pointer */
398       G_VALUE_COLLECT_LONG,     /* collect_type */
399       value_long_collect_value, /* collect_value */
400       G_VALUE_COLLECT_POINTER,  /* lcopy_type */
401       value_long_lcopy_value,   /* lcopy_value */
402     };
403     info.value_table = &value_table;
404     type = g_type_register_fundamental (G_TYPE_LONG, "glong", &info, &finfo, 0);
405     g_assert (type == G_TYPE_LONG);
406     type = g_type_register_fundamental (G_TYPE_ULONG, "gulong", &info, &finfo, 0);
407     g_assert (type == G_TYPE_ULONG);
408   }
409   
410   /* G_TYPE_FLOAT
411    */
412   {
413     static const GTypeValueTable value_table = {
414       value_float_init,          /* value_init */
415       NULL,                      /* value_free */
416       value_float_copy,          /* value_copy */
417       NULL,                      /* value_peek_pointer */
418       G_VALUE_COLLECT_DOUBLE,    /* collect_type */
419       value_float_collect_value, /* collect_value */
420       G_VALUE_COLLECT_POINTER,   /* lcopy_type */
421       value_float_lcopy_value,   /* lcopy_value */
422     };
423     info.value_table = &value_table;
424     type = g_type_register_fundamental (G_TYPE_FLOAT, "gfloat", &info, &finfo, 0);
425     g_assert (type == G_TYPE_FLOAT);
426   }
427   
428   /* G_TYPE_DOUBLE
429    */
430   {
431     static const GTypeValueTable value_table = {
432       value_double_init,          /* value_init */
433       NULL,                       /* value_free */
434       value_double_copy,          /* value_copy */
435       NULL,                       /* value_peek_pointer */
436       G_VALUE_COLLECT_DOUBLE,     /* collect_type */
437       value_double_collect_value, /* collect_value */
438       G_VALUE_COLLECT_POINTER,    /* lcopy_type */
439       value_double_lcopy_value,   /* lcopy_value */
440     };
441     info.value_table = &value_table;
442     type = g_type_register_fundamental (G_TYPE_DOUBLE, "gdouble", &info, &finfo, 0);
443     g_assert (type == G_TYPE_DOUBLE);
444   }
445
446   /* G_TYPE_STRING
447    */
448   {
449     static const GTypeValueTable value_table = {
450       value_string_init,          /* value_init */
451       value_string_free_value,    /* value_free */
452       value_string_copy_value,    /* value_copy */
453       value_pointer_peek_pointer, /* value_peek_pointer */
454       G_VALUE_COLLECT_POINTER,    /* collect_type */
455       value_string_collect_value, /* collect_value */
456       G_VALUE_COLLECT_POINTER,    /* lcopy_type */
457       value_string_lcopy_value,   /* lcopy_value */
458     };
459     info.value_table = &value_table;
460     type = g_type_register_fundamental (G_TYPE_STRING, "gstring", &info, &finfo, 0);
461     g_assert (type == G_TYPE_STRING);
462   }
463
464   /* G_TYPE_POINTER
465    */
466   {
467     static const GTypeValueTable value_table = {
468       value_pointer_init,          /* value_init */
469       NULL,                        /* value_free */
470       value_pointer_copy,          /* value_copy */
471       value_pointer_peek_pointer,  /* value_peek_pointer */
472       G_VALUE_COLLECT_POINTER,     /* collect_type */
473       value_pointer_collect_value, /* collect_value */
474       G_VALUE_COLLECT_POINTER,     /* lcopy_type */
475       value_pointer_lcopy_value,   /* lcopy_value */
476     };
477     info.value_table = &value_table;
478     type = g_type_register_fundamental (G_TYPE_POINTER, "gpointer", &info, &finfo, 0);
479     g_assert (type == G_TYPE_POINTER);
480   }
481 }
482
483
484 /* --- GValue functions --- */
485 void
486 g_value_set_char (GValue *value,
487                   gint8   v_char)
488 {
489   g_return_if_fail (G_IS_VALUE_CHAR (value));
490   
491   value->data[0].v_int = v_char;
492 }
493
494 gint8
495 g_value_get_char (const GValue *value)
496 {
497   g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0);
498   
499   return value->data[0].v_int;
500 }
501
502 void
503 g_value_set_uchar (GValue *value,
504                    guint8  v_uchar)
505 {
506   g_return_if_fail (G_IS_VALUE_UCHAR (value));
507   
508   value->data[0].v_uint = v_uchar;
509 }
510
511 guint8
512 g_value_get_uchar (const GValue *value)
513 {
514   g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0);
515   
516   return value->data[0].v_uint;
517 }
518
519 void
520 g_value_set_boolean (GValue  *value,
521                      gboolean v_boolean)
522 {
523   g_return_if_fail (G_IS_VALUE_BOOLEAN (value));
524   
525   value->data[0].v_int = v_boolean;
526 }
527
528 gboolean
529 g_value_get_boolean (const GValue *value)
530 {
531   g_return_val_if_fail (G_IS_VALUE_BOOLEAN (value), 0);
532   
533   return value->data[0].v_int;
534 }
535
536 void
537 g_value_set_int (GValue *value,
538                  gint    v_int)
539 {
540   g_return_if_fail (G_IS_VALUE_INT (value));
541   
542   value->data[0].v_int = v_int;
543 }
544
545 gint
546 g_value_get_int (const GValue *value)
547 {
548   g_return_val_if_fail (G_IS_VALUE_INT (value), 0);
549   
550   return value->data[0].v_int;
551 }
552
553 void
554 g_value_set_uint (GValue *value,
555                   guint   v_uint)
556 {
557   g_return_if_fail (G_IS_VALUE_UINT (value));
558   
559   value->data[0].v_uint = v_uint;
560 }
561
562 guint
563 g_value_get_uint (const GValue *value)
564 {
565   g_return_val_if_fail (G_IS_VALUE_UINT (value), 0);
566   
567   return value->data[0].v_uint;
568 }
569
570 void
571 g_value_set_long (GValue *value,
572                   glong   v_long)
573 {
574   g_return_if_fail (G_IS_VALUE_LONG (value));
575   
576   value->data[0].v_long = v_long;
577 }
578
579 glong
580 g_value_get_long (const GValue *value)
581 {
582   g_return_val_if_fail (G_IS_VALUE_LONG (value), 0);
583   
584   return value->data[0].v_long;
585 }
586
587 void
588 g_value_set_ulong (GValue *value,
589                    gulong  v_ulong)
590 {
591   g_return_if_fail (G_IS_VALUE_ULONG (value));
592   
593   value->data[0].v_ulong = v_ulong;
594 }
595
596 gulong
597 g_value_get_ulong (const GValue *value)
598 {
599   g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0);
600   
601   return value->data[0].v_ulong;
602 }
603
604 void
605 g_value_set_float (GValue *value,
606                    gfloat  v_float)
607 {
608   g_return_if_fail (G_IS_VALUE_FLOAT (value));
609   
610   value->data[0].v_float = v_float;
611 }
612
613 gfloat
614 g_value_get_float (const GValue *value)
615 {
616   g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0);
617   
618   return value->data[0].v_float;
619 }
620
621 void
622 g_value_set_double (GValue *value,
623                     gdouble v_double)
624 {
625   g_return_if_fail (G_IS_VALUE_DOUBLE (value));
626   
627   value->data[0].v_double = v_double;
628 }
629
630 gdouble
631 g_value_get_double (const GValue *value)
632 {
633   g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0);
634   
635   return value->data[0].v_double;
636 }
637
638 void
639 g_value_set_string (GValue      *value,
640                     const gchar *v_string)
641 {
642   g_return_if_fail (G_IS_VALUE_STRING (value));
643   
644   if (value->data[1].v_uint & G_VALUE_STATIC_TAG)
645     value->data[1].v_uint = 0;
646   else
647     g_free (value->data[0].v_pointer);
648   value->data[0].v_pointer = g_strdup (v_string);
649 }
650
651 void
652 g_value_set_static_string (GValue      *value,
653                            const gchar *v_string)
654 {
655   g_return_if_fail (G_IS_VALUE_STRING (value));
656   
657   if (!(value->data[1].v_uint & G_VALUE_STATIC_TAG))
658     g_free (value->data[0].v_pointer);
659   value->data[1].v_uint = G_VALUE_STATIC_TAG;
660   value->data[0].v_pointer = (gchar*) v_string;
661 }
662
663 gchar*
664 g_value_get_string (const GValue *value)
665 {
666   g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
667   
668   return value->data[0].v_pointer;
669 }
670
671 gchar*
672 g_value_dup_string (const GValue *value)
673 {
674   g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
675   
676   return g_strdup (value->data[0].v_pointer);
677 }
678
679 void
680 g_value_set_pointer (GValue  *value,
681                      gpointer v_pointer)
682 {
683   g_return_if_fail (G_IS_VALUE_POINTER (value));
684
685   value->data[0].v_pointer = v_pointer;
686 }
687
688 gpointer
689 g_value_get_pointer (const GValue *value)
690 {
691   g_return_val_if_fail (G_IS_VALUE_POINTER (value), NULL);
692
693   return value->data[0].v_pointer;
694 }