Make the g_value_set_x_take_ownership() functions "official" part of the
[platform/upstream/glib.git] / gobject / gvaluetypes.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997-1999, 2000-2001 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
20 /*
21  * MT safe
22  */
23
24 #include        "gvaluetypes.h"
25
26 #include        "gvaluecollector.h"
27 #include        <string.h>
28 #include        <stdlib.h>      /* qsort() */
29
30
31 /* --- value functions --- */
32 static void
33 value_init_long0 (GValue *value)
34 {
35   value->data[0].v_long = 0;
36 }
37
38 static void
39 value_copy_long0 (const GValue *src_value,
40                   GValue       *dest_value)
41 {
42   dest_value->data[0].v_long = src_value->data[0].v_long;
43 }
44
45 static gchar*
46 value_lcopy_char (const GValue *value,
47                   guint         n_collect_values,
48                   GTypeCValue  *collect_values,
49                   guint         collect_flags)
50 {
51   gint8 *int8_p = collect_values[0].v_pointer;
52   
53   if (!int8_p)
54     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
55   
56   *int8_p = value->data[0].v_int;
57   
58   return NULL;
59 }
60
61 static gchar*
62 value_lcopy_boolean (const GValue *value,
63                      guint         n_collect_values,
64                      GTypeCValue  *collect_values,
65                      guint         collect_flags)
66 {
67   gboolean *bool_p = collect_values[0].v_pointer;
68   
69   if (!bool_p)
70     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
71   
72   *bool_p = value->data[0].v_int;
73   
74   return NULL;
75 }
76
77 static gchar*
78 value_collect_int (GValue      *value,
79                    guint        n_collect_values,
80                    GTypeCValue *collect_values,
81                    guint        collect_flags)
82 {
83   value->data[0].v_int = collect_values[0].v_int;
84   
85   return NULL;
86 }
87
88 static gchar*
89 value_lcopy_int (const GValue *value,
90                  guint         n_collect_values,
91                  GTypeCValue  *collect_values,
92                  guint         collect_flags)
93 {
94   gint *int_p = collect_values[0].v_pointer;
95   
96   if (!int_p)
97     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
98   
99   *int_p = value->data[0].v_int;
100   
101   return NULL;
102 }
103
104 static gchar*
105 value_collect_long (GValue      *value,
106                     guint        n_collect_values,
107                     GTypeCValue *collect_values,
108                     guint        collect_flags)
109 {
110   value->data[0].v_long = collect_values[0].v_long;
111   
112   return NULL;
113 }
114
115 static gchar*
116 value_lcopy_long (const GValue *value,
117                   guint         n_collect_values,
118                   GTypeCValue  *collect_values,
119                   guint         collect_flags)
120 {
121   glong *long_p = collect_values[0].v_pointer;
122   
123   if (!long_p)
124     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
125   
126   *long_p = value->data[0].v_long;
127   
128   return NULL;
129 }
130
131 static void
132 value_init_int64 (GValue *value)
133 {
134   value->data[0].v_int64 = 0;
135 }
136
137 static void
138 value_copy_int64 (const GValue *src_value,
139                   GValue       *dest_value)
140 {
141   dest_value->data[0].v_int64 = src_value->data[0].v_int64;
142 }
143
144 static gchar*
145 value_collect_int64 (GValue      *value,
146                      guint        n_collect_values,
147                      GTypeCValue *collect_values,
148                      guint        collect_flags)
149 {
150   value->data[0].v_int64 = collect_values[0].v_int64;
151   
152   return NULL;
153 }
154
155 static gchar*
156 value_lcopy_int64 (const GValue *value,
157                    guint         n_collect_values,
158                    GTypeCValue  *collect_values,
159                    guint         collect_flags)
160 {
161   gint64 *int64_p = collect_values[0].v_pointer;
162   
163   if (!int64_p)
164     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
165   
166   *int64_p = value->data[0].v_int64;
167   
168   return NULL;
169 }
170
171 static void
172 value_init_float (GValue *value)
173 {
174   value->data[0].v_float = 0.0;
175 }
176
177 static void
178 value_copy_float (const GValue *src_value,
179                   GValue       *dest_value)
180 {
181   dest_value->data[0].v_float = src_value->data[0].v_float;
182 }
183
184 static gchar*
185 value_collect_float (GValue      *value,
186                      guint        n_collect_values,
187                      GTypeCValue *collect_values,
188                      guint        collect_flags)
189 {
190   value->data[0].v_float = collect_values[0].v_double;
191   
192   return NULL;
193 }
194
195 static gchar*
196 value_lcopy_float (const GValue *value,
197                    guint         n_collect_values,
198                    GTypeCValue  *collect_values,
199                    guint         collect_flags)
200 {
201   gfloat *float_p = collect_values[0].v_pointer;
202   
203   if (!float_p)
204     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
205   
206   *float_p = value->data[0].v_float;
207   
208   return NULL;
209 }
210
211 static void
212 value_init_double (GValue *value)
213 {
214   value->data[0].v_double = 0.0;
215 }
216
217 static void
218 value_copy_double (const GValue *src_value,
219                    GValue       *dest_value)
220 {
221   dest_value->data[0].v_double = src_value->data[0].v_double;
222 }
223
224 static gchar*
225 value_collect_double (GValue      *value,
226                       guint        n_collect_values,
227                       GTypeCValue *collect_values,
228                       guint        collect_flags)
229 {
230   value->data[0].v_double = collect_values[0].v_double;
231   
232   return NULL;
233 }
234
235 static gchar*
236 value_lcopy_double (const GValue *value,
237                     guint         n_collect_values,
238                     GTypeCValue  *collect_values,
239                     guint         collect_flags)
240 {
241   gdouble *double_p = collect_values[0].v_pointer;
242   
243   if (!double_p)
244     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
245   
246   *double_p = value->data[0].v_double;
247   
248   return NULL;
249 }
250
251 static void
252 value_init_string (GValue *value)
253 {
254   value->data[0].v_pointer = NULL;
255 }
256
257 static void
258 value_free_string (GValue *value)
259 {
260   if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
261     g_free (value->data[0].v_pointer);
262 }
263
264 static void
265 value_copy_string (const GValue *src_value,
266                    GValue       *dest_value)
267 {
268   dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
269 }
270
271 static gchar*
272 value_collect_string (GValue      *value,
273                       guint        n_collect_values,
274                       GTypeCValue *collect_values,
275                       guint        collect_flags)
276 {
277   if (!collect_values[0].v_pointer)
278     value->data[0].v_pointer = NULL;
279   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
280     {
281       value->data[0].v_pointer = collect_values[0].v_pointer;
282       value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
283     }
284   else
285     value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
286   
287   return NULL;
288 }
289
290 static gchar*
291 value_lcopy_string (const GValue *value,
292                     guint         n_collect_values,
293                     GTypeCValue  *collect_values,
294                     guint         collect_flags)
295 {
296   gchar **string_p = collect_values[0].v_pointer;
297   
298   if (!string_p)
299     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
300   
301   if (!value->data[0].v_pointer)
302     *string_p = NULL;
303   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
304     *string_p = value->data[0].v_pointer;
305   else
306     *string_p = g_strdup (value->data[0].v_pointer);
307   
308   return NULL;
309 }
310
311 static void
312 value_init_pointer (GValue *value)
313 {
314   value->data[0].v_pointer = NULL;
315 }
316
317 static void
318 value_copy_pointer (const GValue *src_value,
319                     GValue       *dest_value)
320 {
321   dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
322 }
323
324 static gpointer
325 value_peek_pointer0 (const GValue *value)
326 {
327   return value->data[0].v_pointer;
328 }
329
330 static gchar*
331 value_collect_pointer (GValue      *value,
332                        guint        n_collect_values,
333                        GTypeCValue *collect_values,
334                        guint        collect_flags)
335 {
336   value->data[0].v_pointer = collect_values[0].v_pointer;
337
338   return NULL;
339 }
340
341 static gchar*
342 value_lcopy_pointer (const GValue *value,
343                      guint         n_collect_values,
344                      GTypeCValue  *collect_values,
345                      guint         collect_flags)
346 {
347   gpointer *pointer_p = collect_values[0].v_pointer;
348
349   if (!pointer_p)
350     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
351
352   *pointer_p = value->data[0].v_pointer;
353
354   return NULL;
355 }
356
357
358 /* --- type initialization --- */
359 void
360 g_value_types_init (void)  /* sync with gtype.c */
361 {
362   GTypeInfo info = {
363     0,                          /* class_size */
364     NULL,                       /* base_init */
365     NULL,                       /* base_destroy */
366     NULL,                       /* class_init */
367     NULL,                       /* class_destroy */
368     NULL,                       /* class_data */
369     0,                          /* instance_size */
370     0,                          /* n_preallocs */
371     NULL,                       /* instance_init */
372     NULL,                       /* value_table */
373   };
374   const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
375   GType type;
376   
377   /* G_TYPE_CHAR / G_TYPE_UCHAR
378    */
379   {
380     static const GTypeValueTable value_table = {
381       value_init_long0,         /* value_init */
382       NULL,                     /* value_free */
383       value_copy_long0,         /* value_copy */
384       NULL,                     /* value_peek_pointer */
385       "i",                      /* collect_format */
386       value_collect_int,        /* collect_value */
387       "p",                      /* lcopy_format */
388       value_lcopy_char,         /* lcopy_value */
389     };
390     info.value_table = &value_table;
391     type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0);
392     g_assert (type == G_TYPE_CHAR);
393     type = g_type_register_fundamental (G_TYPE_UCHAR, "guchar", &info, &finfo, 0);
394     g_assert (type == G_TYPE_UCHAR);
395   }
396
397   /* G_TYPE_BOOLEAN
398    */
399   {
400     static const GTypeValueTable value_table = {
401       value_init_long0,          /* value_init */
402       NULL,                      /* value_free */
403       value_copy_long0,          /* value_copy */
404       NULL,                      /* value_peek_pointer */
405       "i",                       /* collect_format */
406       value_collect_int,         /* collect_value */
407       "p",                       /* lcopy_format */
408       value_lcopy_boolean,       /* lcopy_value */
409     };
410     info.value_table = &value_table;
411     type = g_type_register_fundamental (G_TYPE_BOOLEAN, "gboolean", &info, &finfo, 0);
412     g_assert (type == G_TYPE_BOOLEAN);
413   }
414   
415   /* G_TYPE_INT / G_TYPE_UINT
416    */
417   {
418     static const GTypeValueTable value_table = {
419       value_init_long0,         /* value_init */
420       NULL,                     /* value_free */
421       value_copy_long0,         /* value_copy */
422       NULL,                     /* value_peek_pointer */
423       "i",                      /* collect_format */
424       value_collect_int,        /* collect_value */
425       "p",                      /* lcopy_format */
426       value_lcopy_int,          /* lcopy_value */
427     };
428     info.value_table = &value_table;
429     type = g_type_register_fundamental (G_TYPE_INT, "gint", &info, &finfo, 0);
430     g_assert (type == G_TYPE_INT);
431     type = g_type_register_fundamental (G_TYPE_UINT, "guint", &info, &finfo, 0);
432     g_assert (type == G_TYPE_UINT);
433   }
434
435   /* G_TYPE_LONG / G_TYPE_ULONG
436    */
437   {
438     static const GTypeValueTable value_table = {
439       value_init_long0,         /* value_init */
440       NULL,                     /* value_free */
441       value_copy_long0,         /* value_copy */
442       NULL,                     /* value_peek_pointer */
443       "l",                      /* collect_format */
444       value_collect_long,       /* collect_value */
445       "p",                      /* lcopy_format */
446       value_lcopy_long,         /* lcopy_value */
447     };
448     info.value_table = &value_table;
449     type = g_type_register_fundamental (G_TYPE_LONG, "glong", &info, &finfo, 0);
450     g_assert (type == G_TYPE_LONG);
451     type = g_type_register_fundamental (G_TYPE_ULONG, "gulong", &info, &finfo, 0);
452     g_assert (type == G_TYPE_ULONG);
453   }
454   
455   /* G_TYPE_INT64 / G_TYPE_UINT64
456    */
457   {
458     static const GTypeValueTable value_table = {
459       value_init_int64,         /* value_init */
460       NULL,                     /* value_free */
461       value_copy_int64,         /* value_copy */
462       NULL,                     /* value_peek_pointer */
463       "q",                      /* collect_format */
464       value_collect_int64,      /* collect_value */
465       "p",                      /* lcopy_format */
466       value_lcopy_int64,        /* lcopy_value */
467     };
468     info.value_table = &value_table;
469     type = g_type_register_fundamental (G_TYPE_INT64, "gint64", &info, &finfo, 0);
470     g_assert (type == G_TYPE_INT64);
471     type = g_type_register_fundamental (G_TYPE_UINT64, "guint64", &info, &finfo, 0);
472     g_assert (type == G_TYPE_UINT64);
473   }
474   
475   /* G_TYPE_FLOAT
476    */
477   {
478     static const GTypeValueTable value_table = {
479       value_init_float,          /* value_init */
480       NULL,                      /* value_free */
481       value_copy_float,          /* value_copy */
482       NULL,                      /* value_peek_pointer */
483       "d",                       /* collect_format */
484       value_collect_float,       /* collect_value */
485       "p",                       /* lcopy_format */
486       value_lcopy_float,         /* lcopy_value */
487     };
488     info.value_table = &value_table;
489     type = g_type_register_fundamental (G_TYPE_FLOAT, "gfloat", &info, &finfo, 0);
490     g_assert (type == G_TYPE_FLOAT);
491   }
492   
493   /* G_TYPE_DOUBLE
494    */
495   {
496     static const GTypeValueTable value_table = {
497       value_init_double,        /* value_init */
498       NULL,                     /* value_free */
499       value_copy_double,        /* value_copy */
500       NULL,                     /* value_peek_pointer */
501       "d",                      /* collect_format */
502       value_collect_double,     /* collect_value */
503       "p",                      /* lcopy_format */
504       value_lcopy_double,       /* lcopy_value */
505     };
506     info.value_table = &value_table;
507     type = g_type_register_fundamental (G_TYPE_DOUBLE, "gdouble", &info, &finfo, 0);
508     g_assert (type == G_TYPE_DOUBLE);
509   }
510
511   /* G_TYPE_STRING
512    */
513   {
514     static const GTypeValueTable value_table = {
515       value_init_string,        /* value_init */
516       value_free_string,        /* value_free */
517       value_copy_string,        /* value_copy */
518       value_peek_pointer0,      /* value_peek_pointer */
519       "p",                      /* collect_format */
520       value_collect_string,     /* collect_value */
521       "p",                      /* lcopy_format */
522       value_lcopy_string,       /* lcopy_value */
523     };
524     info.value_table = &value_table;
525     type = g_type_register_fundamental (G_TYPE_STRING, "gchararray", &info, &finfo, 0);
526     g_assert (type == G_TYPE_STRING);
527   }
528
529   /* G_TYPE_POINTER
530    */
531   {
532     static const GTypeValueTable value_table = {
533       value_init_pointer,       /* value_init */
534       NULL,                     /* value_free */
535       value_copy_pointer,       /* value_copy */
536       value_peek_pointer0,      /* value_peek_pointer */
537       "p",                      /* collect_format */
538       value_collect_pointer,    /* collect_value */
539       "p",                      /* lcopy_format */
540       value_lcopy_pointer,      /* lcopy_value */
541     };
542     info.value_table = &value_table;
543     type = g_type_register_fundamental (G_TYPE_POINTER, "gpointer", &info, &finfo, 0);
544     g_assert (type == G_TYPE_POINTER);
545   }
546 }
547
548
549 /* --- GValue functions --- */
550 void
551 g_value_set_char (GValue *value,
552                   gchar   v_char)
553 {
554   g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
555   
556   value->data[0].v_int = v_char;
557 }
558
559 gchar
560 g_value_get_char (const GValue *value)
561 {
562   g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
563   
564   return value->data[0].v_int;
565 }
566
567 void
568 g_value_set_uchar (GValue *value,
569                    guchar  v_uchar)
570 {
571   g_return_if_fail (G_VALUE_HOLDS_UCHAR (value));
572   
573   value->data[0].v_uint = v_uchar;
574 }
575
576 guchar
577 g_value_get_uchar (const GValue *value)
578 {
579   g_return_val_if_fail (G_VALUE_HOLDS_UCHAR (value), 0);
580   
581   return value->data[0].v_uint;
582 }
583
584 void
585 g_value_set_boolean (GValue  *value,
586                      gboolean v_boolean)
587 {
588   g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
589   
590   value->data[0].v_int = v_boolean != FALSE;
591 }
592
593 gboolean
594 g_value_get_boolean (const GValue *value)
595 {
596   g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (value), 0);
597   
598   return value->data[0].v_int;
599 }
600
601 void
602 g_value_set_int (GValue *value,
603                  gint    v_int)
604 {
605   g_return_if_fail (G_VALUE_HOLDS_INT (value));
606   
607   value->data[0].v_int = v_int;
608 }
609
610 gint
611 g_value_get_int (const GValue *value)
612 {
613   g_return_val_if_fail (G_VALUE_HOLDS_INT (value), 0);
614   
615   return value->data[0].v_int;
616 }
617
618 void
619 g_value_set_uint (GValue *value,
620                   guint   v_uint)
621 {
622   g_return_if_fail (G_VALUE_HOLDS_UINT (value));
623   
624   value->data[0].v_uint = v_uint;
625 }
626
627 guint
628 g_value_get_uint (const GValue *value)
629 {
630   g_return_val_if_fail (G_VALUE_HOLDS_UINT (value), 0);
631   
632   return value->data[0].v_uint;
633 }
634
635 void
636 g_value_set_long (GValue *value,
637                   glong   v_long)
638 {
639   g_return_if_fail (G_VALUE_HOLDS_LONG (value));
640   
641   value->data[0].v_long = v_long;
642 }
643
644 glong
645 g_value_get_long (const GValue *value)
646 {
647   g_return_val_if_fail (G_VALUE_HOLDS_LONG (value), 0);
648   
649   return value->data[0].v_long;
650 }
651
652 void
653 g_value_set_ulong (GValue *value,
654                    gulong  v_ulong)
655 {
656   g_return_if_fail (G_VALUE_HOLDS_ULONG (value));
657   
658   value->data[0].v_ulong = v_ulong;
659 }
660
661 gulong
662 g_value_get_ulong (const GValue *value)
663 {
664   g_return_val_if_fail (G_VALUE_HOLDS_ULONG (value), 0);
665   
666   return value->data[0].v_ulong;
667 }
668
669 void
670 g_value_set_int64 (GValue *value,
671                    gint64  v_int64)
672 {
673   g_return_if_fail (G_VALUE_HOLDS_INT64 (value));
674   
675   value->data[0].v_int64 = v_int64;
676 }
677
678 gint64
679 g_value_get_int64 (const GValue *value)
680 {
681   g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0);
682   
683   return value->data[0].v_int64;
684 }
685
686 void
687 g_value_set_uint64 (GValue *value,
688                     guint64 v_uint64)
689 {
690   g_return_if_fail (G_VALUE_HOLDS_UINT64 (value));
691   
692   value->data[0].v_uint64 = v_uint64;
693 }
694
695 guint64
696 g_value_get_uint64 (const GValue *value)
697 {
698   g_return_val_if_fail (G_VALUE_HOLDS_UINT64 (value), 0);
699   
700   return value->data[0].v_uint64;
701 }
702
703 void
704 g_value_set_float (GValue *value,
705                    gfloat  v_float)
706 {
707   g_return_if_fail (G_VALUE_HOLDS_FLOAT (value));
708   
709   value->data[0].v_float = v_float;
710 }
711
712 gfloat
713 g_value_get_float (const GValue *value)
714 {
715   g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (value), 0);
716   
717   return value->data[0].v_float;
718 }
719
720 void
721 g_value_set_double (GValue *value,
722                     gdouble v_double)
723 {
724   g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value));
725   
726   value->data[0].v_double = v_double;
727 }
728
729 gdouble
730 g_value_get_double (const GValue *value)
731 {
732   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (value), 0);
733   
734   return value->data[0].v_double;
735 }
736
737 void
738 g_value_set_string (GValue      *value,
739                     const gchar *v_string)
740 {
741   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
742   
743   if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
744     value->data[1].v_uint = 0;
745   else
746     g_free (value->data[0].v_pointer);
747   value->data[0].v_pointer = g_strdup (v_string);
748 }
749
750 void
751 g_value_set_static_string (GValue      *value,
752                            const gchar *v_string)
753 {
754   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
755   
756   if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
757     g_free (value->data[0].v_pointer);
758   value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
759   value->data[0].v_pointer = (gchar*) v_string;
760 }
761
762 void
763 g_value_set_string_take_ownership (GValue *value,
764                                    gchar  *v_string)
765 {
766   g_value_take_string (value, v_string);
767 }
768
769 void
770 g_value_take_string (GValue *value,
771                      gchar  *v_string)
772 {
773   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
774   
775   if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
776     value->data[1].v_uint = 0;
777   else
778     g_free (value->data[0].v_pointer);
779   value->data[0].v_pointer = v_string;
780 }
781
782 G_CONST_RETURN gchar*
783 g_value_get_string (const GValue *value)
784 {
785   g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
786   
787   return value->data[0].v_pointer;
788 }
789
790 gchar*
791 g_value_dup_string (const GValue *value)
792 {
793   g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
794   
795   return g_strdup (value->data[0].v_pointer);
796 }
797
798 void
799 g_value_set_pointer (GValue  *value,
800                      gpointer v_pointer)
801 {
802   g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
803
804   value->data[0].v_pointer = v_pointer;
805 }
806
807 gpointer
808 g_value_get_pointer (const GValue *value)
809 {
810   g_return_val_if_fail (G_VALUE_HOLDS_POINTER (value), NULL);
811
812   return value->data[0].v_pointer;
813 }
814
815 /* need extra includes for g_strdup_value_contents() ;( */
816 #include "gobject.h"
817 #include "gparam.h"
818 #include "gboxed.h"
819 #include "genums.h"
820
821 gchar*
822 g_strdup_value_contents (const GValue *value)
823 {
824   const gchar *src;
825   gchar *contents;
826
827   g_return_val_if_fail (G_IS_VALUE (value), NULL);
828   
829   if (G_VALUE_HOLDS_STRING (value))
830     {
831       src = g_value_get_string (value);
832       
833       if (!src)
834         contents = g_strdup ("NULL");
835       else
836         {
837           gchar *s = g_strescape (src, NULL);
838
839           contents = g_strdup_printf ("\"%s\"", s);
840           g_free (s);
841         }
842     }
843   else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
844     {
845       GValue tmp_value = { 0, };
846       gchar *s;
847
848       g_value_init (&tmp_value, G_TYPE_STRING);
849       g_value_transform (value, &tmp_value);
850       s = g_strescape (g_value_get_string (&tmp_value), NULL);
851       g_value_unset (&tmp_value);
852       if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value))
853         contents = g_strdup_printf ("((%s) %s)",
854                                     g_type_name (G_VALUE_TYPE (value)),
855                                     s);
856       else
857         contents = g_strdup (s ? s : "NULL");
858       g_free (s);
859     }
860   else if (g_value_fits_pointer (value))
861     {
862       gpointer p = g_value_peek_pointer (value);
863
864       if (!p)
865         contents = g_strdup ("NULL");
866       else if (G_VALUE_HOLDS_OBJECT (value))
867         contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p);
868       else if (G_VALUE_HOLDS_PARAM (value))
869         contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p);
870       else if (G_VALUE_HOLDS_BOXED (value))
871         contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p);
872       else if (G_VALUE_HOLDS_POINTER (value))
873         contents = g_strdup_printf ("((gpointer) %p)", p);
874       else
875         contents = g_strdup ("???");
876     }
877   else
878     contents = g_strdup ("???");
879
880   return contents;
881 }
882
883 GType
884 g_pointer_type_register_static (const gchar *name)
885 {
886   static const GTypeInfo type_info = {
887     0,                  /* class_size */
888     NULL,               /* base_init */
889     NULL,               /* base_finalize */
890     NULL,               /* class_init */
891     NULL,               /* class_finalize */
892     NULL,               /* class_data */
893     0,                  /* instance_size */
894     0,                  /* n_preallocs */
895     NULL,               /* instance_init */
896     NULL                /* value_table */
897   };
898   GType type;
899
900   g_return_val_if_fail (name != NULL, 0);
901   g_return_val_if_fail (g_type_from_name (name) == 0, 0);
902
903   type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0);
904
905   return type;
906 }
907