• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  * Copyright © 2010 Christian Persch
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /*
20  * MT safe
21  */
22 
23 #include "config.h"
24 
25 #include <string.h>
26 #include <stdlib.h> /* qsort() */
27 
28 #include "gvaluetypes.h"
29 #include "gtype-private.h"
30 #include "gvaluecollector.h"
31 #include "gobject.h"
32 #include "gparam.h"
33 #include "gboxed.h"
34 #include "genums.h"
35 
36 
37 /* --- value functions --- */
38 static void
value_init_long0(GValue * value)39 value_init_long0 (GValue *value)
40 {
41   value->data[0].v_long = 0;
42 }
43 
44 static void
value_copy_long0(const GValue * src_value,GValue * dest_value)45 value_copy_long0 (const GValue *src_value,
46 		  GValue       *dest_value)
47 {
48   dest_value->data[0].v_long = src_value->data[0].v_long;
49 }
50 
51 static gchar*
value_lcopy_char(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)52 value_lcopy_char (const GValue *value,
53 		  guint         n_collect_values,
54 		  GTypeCValue  *collect_values,
55 		  guint         collect_flags)
56 {
57   gint8 *int8_p = collect_values[0].v_pointer;
58 
59   if (!int8_p)
60     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
61 
62   *int8_p = value->data[0].v_int;
63 
64   return NULL;
65 }
66 
67 static gchar*
value_lcopy_boolean(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)68 value_lcopy_boolean (const GValue *value,
69 		     guint         n_collect_values,
70 		     GTypeCValue  *collect_values,
71 		     guint         collect_flags)
72 {
73   gboolean *bool_p = collect_values[0].v_pointer;
74 
75   if (!bool_p)
76     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
77 
78   *bool_p = value->data[0].v_int;
79 
80   return NULL;
81 }
82 
83 static gchar*
value_collect_int(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)84 value_collect_int (GValue      *value,
85 		   guint        n_collect_values,
86 		   GTypeCValue *collect_values,
87 		   guint        collect_flags)
88 {
89   value->data[0].v_int = collect_values[0].v_int;
90 
91   return NULL;
92 }
93 
94 static gchar*
value_lcopy_int(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)95 value_lcopy_int (const GValue *value,
96 		 guint         n_collect_values,
97 		 GTypeCValue  *collect_values,
98 		 guint         collect_flags)
99 {
100   gint *int_p = collect_values[0].v_pointer;
101 
102   if (!int_p)
103     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
104 
105   *int_p = value->data[0].v_int;
106 
107   return NULL;
108 }
109 
110 static gchar*
value_collect_long(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)111 value_collect_long (GValue      *value,
112 		    guint        n_collect_values,
113 		    GTypeCValue *collect_values,
114 		    guint        collect_flags)
115 {
116   value->data[0].v_long = collect_values[0].v_long;
117 
118   return NULL;
119 }
120 
121 static gchar*
value_lcopy_long(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)122 value_lcopy_long (const GValue *value,
123 		  guint         n_collect_values,
124 		  GTypeCValue  *collect_values,
125 		  guint         collect_flags)
126 {
127   glong *long_p = collect_values[0].v_pointer;
128 
129   if (!long_p)
130     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
131 
132   *long_p = value->data[0].v_long;
133 
134   return NULL;
135 }
136 
137 static void
value_init_int64(GValue * value)138 value_init_int64 (GValue *value)
139 {
140   value->data[0].v_int64 = 0;
141 }
142 
143 static void
value_copy_int64(const GValue * src_value,GValue * dest_value)144 value_copy_int64 (const GValue *src_value,
145 		  GValue       *dest_value)
146 {
147   dest_value->data[0].v_int64 = src_value->data[0].v_int64;
148 }
149 
150 static gchar*
value_collect_int64(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)151 value_collect_int64 (GValue      *value,
152 		     guint        n_collect_values,
153 		     GTypeCValue *collect_values,
154 		     guint        collect_flags)
155 {
156   value->data[0].v_int64 = collect_values[0].v_int64;
157 
158   return NULL;
159 }
160 
161 static gchar*
value_lcopy_int64(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)162 value_lcopy_int64 (const GValue *value,
163 		   guint         n_collect_values,
164 		   GTypeCValue  *collect_values,
165 		   guint         collect_flags)
166 {
167   gint64 *int64_p = collect_values[0].v_pointer;
168 
169   if (!int64_p)
170     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
171 
172   *int64_p = value->data[0].v_int64;
173 
174   return NULL;
175 }
176 
177 static void
value_init_float(GValue * value)178 value_init_float (GValue *value)
179 {
180   value->data[0].v_float = 0.0;
181 }
182 
183 static void
value_copy_float(const GValue * src_value,GValue * dest_value)184 value_copy_float (const GValue *src_value,
185 		  GValue       *dest_value)
186 {
187   dest_value->data[0].v_float = src_value->data[0].v_float;
188 }
189 
190 static gchar*
value_collect_float(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)191 value_collect_float (GValue      *value,
192 		     guint        n_collect_values,
193 		     GTypeCValue *collect_values,
194 		     guint        collect_flags)
195 {
196   value->data[0].v_float = collect_values[0].v_double;
197 
198   return NULL;
199 }
200 
201 static gchar*
value_lcopy_float(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)202 value_lcopy_float (const GValue *value,
203 		   guint         n_collect_values,
204 		   GTypeCValue  *collect_values,
205 		   guint         collect_flags)
206 {
207   gfloat *float_p = collect_values[0].v_pointer;
208 
209   if (!float_p)
210     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
211 
212   *float_p = value->data[0].v_float;
213 
214   return NULL;
215 }
216 
217 static void
value_init_double(GValue * value)218 value_init_double (GValue *value)
219 {
220   value->data[0].v_double = 0.0;
221 }
222 
223 static void
value_copy_double(const GValue * src_value,GValue * dest_value)224 value_copy_double (const GValue *src_value,
225 		   GValue	*dest_value)
226 {
227   dest_value->data[0].v_double = src_value->data[0].v_double;
228 }
229 
230 static gchar*
value_collect_double(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)231 value_collect_double (GValue	  *value,
232 		      guint        n_collect_values,
233 		      GTypeCValue *collect_values,
234 		      guint        collect_flags)
235 {
236   value->data[0].v_double = collect_values[0].v_double;
237 
238   return NULL;
239 }
240 
241 static gchar*
value_lcopy_double(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)242 value_lcopy_double (const GValue *value,
243 		    guint         n_collect_values,
244 		    GTypeCValue  *collect_values,
245 		    guint         collect_flags)
246 {
247   gdouble *double_p = collect_values[0].v_pointer;
248 
249   if (!double_p)
250     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
251 
252   *double_p = value->data[0].v_double;
253 
254   return NULL;
255 }
256 
257 static void
value_init_string(GValue * value)258 value_init_string (GValue *value)
259 {
260   value->data[0].v_pointer = NULL;
261 }
262 
263 static void
value_free_string(GValue * value)264 value_free_string (GValue *value)
265 {
266   if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
267     g_free (value->data[0].v_pointer);
268 }
269 
270 static void
value_copy_string(const GValue * src_value,GValue * dest_value)271 value_copy_string (const GValue *src_value,
272 		   GValue	*dest_value)
273 {
274   dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
275 }
276 
277 static gchar*
value_collect_string(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)278 value_collect_string (GValue	  *value,
279 		      guint        n_collect_values,
280 		      GTypeCValue *collect_values,
281 		      guint        collect_flags)
282 {
283   if (!collect_values[0].v_pointer)
284     value->data[0].v_pointer = NULL;
285   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
286     {
287       value->data[0].v_pointer = collect_values[0].v_pointer;
288       value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
289     }
290   else
291     value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
292 
293   return NULL;
294 }
295 
296 static gchar*
value_lcopy_string(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)297 value_lcopy_string (const GValue *value,
298 		    guint         n_collect_values,
299 		    GTypeCValue  *collect_values,
300 		    guint         collect_flags)
301 {
302   gchar **string_p = collect_values[0].v_pointer;
303 
304   if (!string_p)
305     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
306 
307   if (!value->data[0].v_pointer)
308     *string_p = NULL;
309   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
310     *string_p = value->data[0].v_pointer;
311   else
312     *string_p = g_strdup (value->data[0].v_pointer);
313 
314   return NULL;
315 }
316 
317 static void
value_init_pointer(GValue * value)318 value_init_pointer (GValue *value)
319 {
320   value->data[0].v_pointer = NULL;
321 }
322 
323 static void
value_copy_pointer(const GValue * src_value,GValue * dest_value)324 value_copy_pointer (const GValue *src_value,
325 		    GValue       *dest_value)
326 {
327   dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
328 }
329 
330 static gpointer
value_peek_pointer0(const GValue * value)331 value_peek_pointer0 (const GValue *value)
332 {
333   return value->data[0].v_pointer;
334 }
335 
336 static gchar*
value_collect_pointer(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)337 value_collect_pointer (GValue      *value,
338 		       guint        n_collect_values,
339 		       GTypeCValue *collect_values,
340 		       guint        collect_flags)
341 {
342   value->data[0].v_pointer = collect_values[0].v_pointer;
343 
344   return NULL;
345 }
346 
347 static gchar*
value_lcopy_pointer(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)348 value_lcopy_pointer (const GValue *value,
349 		     guint         n_collect_values,
350 		     GTypeCValue  *collect_values,
351 		     guint         collect_flags)
352 {
353   gpointer *pointer_p = collect_values[0].v_pointer;
354 
355   if (!pointer_p)
356     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
357 
358   *pointer_p = value->data[0].v_pointer;
359 
360   return NULL;
361 }
362 
363 static void
value_free_variant(GValue * value)364 value_free_variant (GValue *value)
365 {
366   if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) &&
367       value->data[0].v_pointer)
368     g_variant_unref (value->data[0].v_pointer);
369 }
370 
371 static void
value_copy_variant(const GValue * src_value,GValue * dest_value)372 value_copy_variant (const GValue *src_value,
373 		   GValue	*dest_value)
374 {
375   if (src_value->data[0].v_pointer)
376     dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer);
377   else
378     dest_value->data[0].v_pointer = NULL;
379 }
380 
381 static gchar*
value_collect_variant(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)382 value_collect_variant (GValue	  *value,
383 		      guint        n_collect_values,
384 		      GTypeCValue *collect_values,
385 		      guint        collect_flags)
386 {
387   if (!collect_values[0].v_pointer)
388     value->data[0].v_pointer = NULL;
389   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
390     {
391       value->data[0].v_pointer = collect_values[0].v_pointer;
392       value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
393     }
394   else
395     value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer);
396 
397   return NULL;
398 }
399 
400 static gchar*
value_lcopy_variant(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)401 value_lcopy_variant (const GValue *value,
402 		    guint         n_collect_values,
403 		    GTypeCValue  *collect_values,
404 		    guint         collect_flags)
405 {
406   GVariant **variant_p = collect_values[0].v_pointer;
407 
408   if (!variant_p)
409     return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
410 
411   if (!value->data[0].v_pointer)
412     *variant_p = NULL;
413   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
414     *variant_p = value->data[0].v_pointer;
415   else
416     *variant_p = g_variant_ref_sink (value->data[0].v_pointer);
417 
418   return NULL;
419 }
420 
421 /* --- type initialization --- */
422 void
_g_value_types_init(void)423 _g_value_types_init (void)
424 {
425   GTypeInfo info = {
426     0,				/* class_size */
427     NULL,			/* base_init */
428     NULL,			/* base_destroy */
429     NULL,			/* class_init */
430     NULL,			/* class_destroy */
431     NULL,			/* class_data */
432     0,				/* instance_size */
433     0,				/* n_preallocs */
434     NULL,			/* instance_init */
435     NULL,			/* value_table */
436   };
437   const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
438   GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
439 
440   /* G_TYPE_CHAR / G_TYPE_UCHAR
441    */
442   {
443     static const GTypeValueTable value_table = {
444       value_init_long0,		/* value_init */
445       NULL,			/* value_free */
446       value_copy_long0,		/* value_copy */
447       NULL,			/* value_peek_pointer */
448       "i",			/* collect_format */
449       value_collect_int,	/* collect_value */
450       "p",			/* lcopy_format */
451       value_lcopy_char,		/* lcopy_value */
452     };
453     info.value_table = &value_table;
454     type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0);
455     g_assert (type == G_TYPE_CHAR);
456     type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0);
457     g_assert (type == G_TYPE_UCHAR);
458   }
459 
460   /* G_TYPE_BOOLEAN
461    */
462   {
463     static const GTypeValueTable value_table = {
464       value_init_long0,		 /* value_init */
465       NULL,			 /* value_free */
466       value_copy_long0,		 /* value_copy */
467       NULL,                      /* value_peek_pointer */
468       "i",			 /* collect_format */
469       value_collect_int,	 /* collect_value */
470       "p",			 /* lcopy_format */
471       value_lcopy_boolean,	 /* lcopy_value */
472     };
473     info.value_table = &value_table;
474     type = g_type_register_fundamental (G_TYPE_BOOLEAN, g_intern_static_string ("gboolean"), &info, &finfo, 0);
475     g_assert (type == G_TYPE_BOOLEAN);
476   }
477 
478   /* G_TYPE_INT / G_TYPE_UINT
479    */
480   {
481     static const GTypeValueTable value_table = {
482       value_init_long0,		/* value_init */
483       NULL,			/* value_free */
484       value_copy_long0,		/* value_copy */
485       NULL,                     /* value_peek_pointer */
486       "i",			/* collect_format */
487       value_collect_int,	/* collect_value */
488       "p",			/* lcopy_format */
489       value_lcopy_int,		/* lcopy_value */
490     };
491     info.value_table = &value_table;
492     type = g_type_register_fundamental (G_TYPE_INT, g_intern_static_string ("gint"), &info, &finfo, 0);
493     g_assert (type == G_TYPE_INT);
494     type = g_type_register_fundamental (G_TYPE_UINT, g_intern_static_string ("guint"), &info, &finfo, 0);
495     g_assert (type == G_TYPE_UINT);
496   }
497 
498   /* G_TYPE_LONG / G_TYPE_ULONG
499    */
500   {
501     static const GTypeValueTable value_table = {
502       value_init_long0,		/* value_init */
503       NULL,			/* value_free */
504       value_copy_long0,		/* value_copy */
505       NULL,                     /* value_peek_pointer */
506       "l",			/* collect_format */
507       value_collect_long,	/* collect_value */
508       "p",			/* lcopy_format */
509       value_lcopy_long,		/* lcopy_value */
510     };
511     info.value_table = &value_table;
512     type = g_type_register_fundamental (G_TYPE_LONG, g_intern_static_string ("glong"), &info, &finfo, 0);
513     g_assert (type == G_TYPE_LONG);
514     type = g_type_register_fundamental (G_TYPE_ULONG, g_intern_static_string ("gulong"), &info, &finfo, 0);
515     g_assert (type == G_TYPE_ULONG);
516   }
517 
518   /* G_TYPE_INT64 / G_TYPE_UINT64
519    */
520   {
521     static const GTypeValueTable value_table = {
522       value_init_int64,		/* value_init */
523       NULL,			/* value_free */
524       value_copy_int64,		/* value_copy */
525       NULL,                     /* value_peek_pointer */
526       "q",			/* collect_format */
527       value_collect_int64,	/* collect_value */
528       "p",			/* lcopy_format */
529       value_lcopy_int64,	/* lcopy_value */
530     };
531     info.value_table = &value_table;
532     type = g_type_register_fundamental (G_TYPE_INT64, g_intern_static_string ("gint64"), &info, &finfo, 0);
533     g_assert (type == G_TYPE_INT64);
534     type = g_type_register_fundamental (G_TYPE_UINT64, g_intern_static_string ("guint64"), &info, &finfo, 0);
535     g_assert (type == G_TYPE_UINT64);
536   }
537 
538   /* G_TYPE_FLOAT
539    */
540   {
541     static const GTypeValueTable value_table = {
542       value_init_float,		 /* value_init */
543       NULL,			 /* value_free */
544       value_copy_float,		 /* value_copy */
545       NULL,                      /* value_peek_pointer */
546       "d",			 /* collect_format */
547       value_collect_float,	 /* collect_value */
548       "p",			 /* lcopy_format */
549       value_lcopy_float,	 /* lcopy_value */
550     };
551     info.value_table = &value_table;
552     type = g_type_register_fundamental (G_TYPE_FLOAT, g_intern_static_string ("gfloat"), &info, &finfo, 0);
553     g_assert (type == G_TYPE_FLOAT);
554   }
555 
556   /* G_TYPE_DOUBLE
557    */
558   {
559     static const GTypeValueTable value_table = {
560       value_init_double,	/* value_init */
561       NULL,			/* value_free */
562       value_copy_double,	/* value_copy */
563       NULL,                     /* value_peek_pointer */
564       "d",			/* collect_format */
565       value_collect_double,	/* collect_value */
566       "p",			/* lcopy_format */
567       value_lcopy_double,	/* lcopy_value */
568     };
569     info.value_table = &value_table;
570     type = g_type_register_fundamental (G_TYPE_DOUBLE, g_intern_static_string ("gdouble"), &info, &finfo, 0);
571     g_assert (type == G_TYPE_DOUBLE);
572   }
573 
574   /* G_TYPE_STRING
575    */
576   {
577     static const GTypeValueTable value_table = {
578       value_init_string,	/* value_init */
579       value_free_string,	/* value_free */
580       value_copy_string,	/* value_copy */
581       value_peek_pointer0,	/* value_peek_pointer */
582       "p",			/* collect_format */
583       value_collect_string,	/* collect_value */
584       "p",			/* lcopy_format */
585       value_lcopy_string,	/* lcopy_value */
586     };
587     info.value_table = &value_table;
588     type = g_type_register_fundamental (G_TYPE_STRING, g_intern_static_string ("gchararray"), &info, &finfo, 0);
589     g_assert (type == G_TYPE_STRING);
590   }
591 
592   /* G_TYPE_POINTER
593    */
594   {
595     static const GTypeValueTable value_table = {
596       value_init_pointer,	/* value_init */
597       NULL,			/* value_free */
598       value_copy_pointer,	/* value_copy */
599       value_peek_pointer0,	/* value_peek_pointer */
600       "p",			/* collect_format */
601       value_collect_pointer,	/* collect_value */
602       "p",			/* lcopy_format */
603       value_lcopy_pointer,	/* lcopy_value */
604     };
605     info.value_table = &value_table;
606     type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0);
607     g_assert (type == G_TYPE_POINTER);
608   }
609 
610   /* G_TYPE_VARIANT
611    */
612   {
613     static const GTypeValueTable value_table = {
614       value_init_pointer,	/* value_init */
615       value_free_variant,	/* value_free */
616       value_copy_variant,	/* value_copy */
617       value_peek_pointer0,	/* value_peek_pointer */
618       "p",			/* collect_format */
619       value_collect_variant,	/* collect_value */
620       "p",			/* lcopy_format */
621       value_lcopy_variant,	/* lcopy_value */
622     };
623     info.value_table = &value_table;
624     type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0);
625     g_assert (type == G_TYPE_VARIANT);
626   }
627 }
628 
629 
630 /* --- GValue functions --- */
631 /**
632  * g_value_set_char:
633  * @value: a valid #GValue of type %G_TYPE_CHAR
634  * @v_char: character value to be set
635  *
636  * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
637  * Deprecated: 2.32: This function's input type is broken, see g_value_set_schar()
638  */
639 void
g_value_set_char(GValue * value,gchar v_char)640 g_value_set_char (GValue *value,
641 		  gchar	  v_char)
642 {
643   g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
644 
645   value->data[0].v_int = v_char;
646 }
647 
648 /**
649  * g_value_get_char:
650  * @value: a valid #GValue of type %G_TYPE_CHAR
651  *
652  * Do not use this function; it is broken on platforms where the %char
653  * type is unsigned, such as ARM and PowerPC.  See g_value_get_schar().
654  *
655  * Get the contents of a %G_TYPE_CHAR #GValue.
656  *
657  * Returns: character contents of @value
658  * Deprecated: 2.32: This function's return type is broken, see g_value_get_schar()
659  */
660 gchar
g_value_get_char(const GValue * value)661 g_value_get_char (const GValue *value)
662 {
663   g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
664 
665   return value->data[0].v_int;
666 }
667 
668 /**
669  * g_value_set_schar:
670  * @value: a valid #GValue of type %G_TYPE_CHAR
671  * @v_char: signed 8 bit integer to be set
672  *
673  * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
674  *
675  * Since: 2.32
676  */
677 void
g_value_set_schar(GValue * value,gint8 v_char)678 g_value_set_schar (GValue *value,
679 		   gint8   v_char)
680 {
681   g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
682 
683   value->data[0].v_int = v_char;
684 }
685 
686 /**
687  * g_value_get_schar:
688  * @value: a valid #GValue of type %G_TYPE_CHAR
689  *
690  * Get the contents of a %G_TYPE_CHAR #GValue.
691  *
692  * Returns: signed 8 bit integer contents of @value
693  * Since: 2.32
694  */
695 gint8
g_value_get_schar(const GValue * value)696 g_value_get_schar (const GValue *value)
697 {
698   g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
699 
700   return value->data[0].v_int;
701 }
702 
703 /**
704  * g_value_set_uchar:
705  * @value: a valid #GValue of type %G_TYPE_UCHAR
706  * @v_uchar: unsigned character value to be set
707  *
708  * Set the contents of a %G_TYPE_UCHAR #GValue to @v_uchar.
709  */
710 void
g_value_set_uchar(GValue * value,guchar v_uchar)711 g_value_set_uchar (GValue *value,
712 		   guchar  v_uchar)
713 {
714   g_return_if_fail (G_VALUE_HOLDS_UCHAR (value));
715 
716   value->data[0].v_uint = v_uchar;
717 }
718 
719 /**
720  * g_value_get_uchar:
721  * @value: a valid #GValue of type %G_TYPE_UCHAR
722  *
723  * Get the contents of a %G_TYPE_UCHAR #GValue.
724  *
725  * Returns: unsigned character contents of @value
726  */
727 guchar
g_value_get_uchar(const GValue * value)728 g_value_get_uchar (const GValue *value)
729 {
730   g_return_val_if_fail (G_VALUE_HOLDS_UCHAR (value), 0);
731 
732   return value->data[0].v_uint;
733 }
734 
735 /**
736  * g_value_set_boolean:
737  * @value: a valid #GValue of type %G_TYPE_BOOLEAN
738  * @v_boolean: boolean value to be set
739  *
740  * Set the contents of a %G_TYPE_BOOLEAN #GValue to @v_boolean.
741  */
742 void
g_value_set_boolean(GValue * value,gboolean v_boolean)743 g_value_set_boolean (GValue  *value,
744 		     gboolean v_boolean)
745 {
746   g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
747 
748   value->data[0].v_int = v_boolean != FALSE;
749 }
750 
751 /**
752  * g_value_get_boolean:
753  * @value: a valid #GValue of type %G_TYPE_BOOLEAN
754  *
755  * Get the contents of a %G_TYPE_BOOLEAN #GValue.
756  *
757  * Returns: boolean contents of @value
758  */
759 gboolean
g_value_get_boolean(const GValue * value)760 g_value_get_boolean (const GValue *value)
761 {
762   g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (value), 0);
763 
764   return value->data[0].v_int;
765 }
766 
767 /**
768  * g_value_set_int:
769  * @value: a valid #GValue of type %G_TYPE_INT
770  * @v_int: integer value to be set
771  *
772  * Set the contents of a %G_TYPE_INT #GValue to @v_int.
773  */
774 void
g_value_set_int(GValue * value,gint v_int)775 g_value_set_int (GValue *value,
776 		 gint	 v_int)
777 {
778   g_return_if_fail (G_VALUE_HOLDS_INT (value));
779 
780   value->data[0].v_int = v_int;
781 }
782 
783 /**
784  * g_value_get_int:
785  * @value: a valid #GValue of type %G_TYPE_INT
786  *
787  * Get the contents of a %G_TYPE_INT #GValue.
788  *
789  * Returns: integer contents of @value
790  */
791 gint
g_value_get_int(const GValue * value)792 g_value_get_int (const GValue *value)
793 {
794   g_return_val_if_fail (G_VALUE_HOLDS_INT (value), 0);
795 
796   return value->data[0].v_int;
797 }
798 
799 /**
800  * g_value_set_uint:
801  * @value: a valid #GValue of type %G_TYPE_UINT
802  * @v_uint: unsigned integer value to be set
803  *
804  * Set the contents of a %G_TYPE_UINT #GValue to @v_uint.
805  */
806 void
g_value_set_uint(GValue * value,guint v_uint)807 g_value_set_uint (GValue *value,
808 		  guint	  v_uint)
809 {
810   g_return_if_fail (G_VALUE_HOLDS_UINT (value));
811 
812   value->data[0].v_uint = v_uint;
813 }
814 
815 /**
816  * g_value_get_uint:
817  * @value: a valid #GValue of type %G_TYPE_UINT
818  *
819  * Get the contents of a %G_TYPE_UINT #GValue.
820  *
821  * Returns: unsigned integer contents of @value
822  */
823 guint
g_value_get_uint(const GValue * value)824 g_value_get_uint (const GValue *value)
825 {
826   g_return_val_if_fail (G_VALUE_HOLDS_UINT (value), 0);
827 
828   return value->data[0].v_uint;
829 }
830 
831 /**
832  * g_value_set_long:
833  * @value: a valid #GValue of type %G_TYPE_LONG
834  * @v_long: long integer value to be set
835  *
836  * Set the contents of a %G_TYPE_LONG #GValue to @v_long.
837  */
838 void
g_value_set_long(GValue * value,glong v_long)839 g_value_set_long (GValue *value,
840 		  glong	  v_long)
841 {
842   g_return_if_fail (G_VALUE_HOLDS_LONG (value));
843 
844   value->data[0].v_long = v_long;
845 }
846 
847 /**
848  * g_value_get_long:
849  * @value: a valid #GValue of type %G_TYPE_LONG
850  *
851  * Get the contents of a %G_TYPE_LONG #GValue.
852  *
853  * Returns: long integer contents of @value
854  */
855 glong
g_value_get_long(const GValue * value)856 g_value_get_long (const GValue *value)
857 {
858   g_return_val_if_fail (G_VALUE_HOLDS_LONG (value), 0);
859 
860   return value->data[0].v_long;
861 }
862 
863 /**
864  * g_value_set_ulong:
865  * @value: a valid #GValue of type %G_TYPE_ULONG
866  * @v_ulong: unsigned long integer value to be set
867  *
868  * Set the contents of a %G_TYPE_ULONG #GValue to @v_ulong.
869  */
870 void
g_value_set_ulong(GValue * value,gulong v_ulong)871 g_value_set_ulong (GValue *value,
872 		   gulong  v_ulong)
873 {
874   g_return_if_fail (G_VALUE_HOLDS_ULONG (value));
875 
876   value->data[0].v_ulong = v_ulong;
877 }
878 
879 /**
880  * g_value_get_ulong:
881  * @value: a valid #GValue of type %G_TYPE_ULONG
882  *
883  * Get the contents of a %G_TYPE_ULONG #GValue.
884  *
885  * Returns: unsigned long integer contents of @value
886  */
887 gulong
g_value_get_ulong(const GValue * value)888 g_value_get_ulong (const GValue *value)
889 {
890   g_return_val_if_fail (G_VALUE_HOLDS_ULONG (value), 0);
891 
892   return value->data[0].v_ulong;
893 }
894 
895 /**
896  * g_value_get_int64:
897  * @value: a valid #GValue of type %G_TYPE_INT64
898  *
899  * Get the contents of a %G_TYPE_INT64 #GValue.
900  *
901  * Returns: 64bit integer contents of @value
902  */
903 void
g_value_set_int64(GValue * value,gint64 v_int64)904 g_value_set_int64 (GValue *value,
905 		   gint64  v_int64)
906 {
907   g_return_if_fail (G_VALUE_HOLDS_INT64 (value));
908 
909   value->data[0].v_int64 = v_int64;
910 }
911 
912 /**
913  * g_value_set_int64:
914  * @value: a valid #GValue of type %G_TYPE_INT64
915  * @v_int64: 64bit integer value to be set
916  *
917  * Set the contents of a %G_TYPE_INT64 #GValue to @v_int64.
918  */
919 gint64
g_value_get_int64(const GValue * value)920 g_value_get_int64 (const GValue *value)
921 {
922   g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0);
923 
924   return value->data[0].v_int64;
925 }
926 
927 /**
928  * g_value_set_uint64:
929  * @value: a valid #GValue of type %G_TYPE_UINT64
930  * @v_uint64: unsigned 64bit integer value to be set
931  *
932  * Set the contents of a %G_TYPE_UINT64 #GValue to @v_uint64.
933  */
934 void
g_value_set_uint64(GValue * value,guint64 v_uint64)935 g_value_set_uint64 (GValue *value,
936 		    guint64 v_uint64)
937 {
938   g_return_if_fail (G_VALUE_HOLDS_UINT64 (value));
939 
940   value->data[0].v_uint64 = v_uint64;
941 }
942 
943 /**
944  * g_value_get_uint64:
945  * @value: a valid #GValue of type %G_TYPE_UINT64
946  *
947  * Get the contents of a %G_TYPE_UINT64 #GValue.
948  *
949  * Returns: unsigned 64bit integer contents of @value
950  */
951 guint64
g_value_get_uint64(const GValue * value)952 g_value_get_uint64 (const GValue *value)
953 {
954   g_return_val_if_fail (G_VALUE_HOLDS_UINT64 (value), 0);
955 
956   return value->data[0].v_uint64;
957 }
958 
959 /**
960  * g_value_set_float:
961  * @value: a valid #GValue of type %G_TYPE_FLOAT
962  * @v_float: float value to be set
963  *
964  * Set the contents of a %G_TYPE_FLOAT #GValue to @v_float.
965  */
966 void
g_value_set_float(GValue * value,gfloat v_float)967 g_value_set_float (GValue *value,
968 		   gfloat  v_float)
969 {
970   g_return_if_fail (G_VALUE_HOLDS_FLOAT (value));
971 
972   value->data[0].v_float = v_float;
973 }
974 
975 /**
976  * g_value_get_float:
977  * @value: a valid #GValue of type %G_TYPE_FLOAT
978  *
979  * Get the contents of a %G_TYPE_FLOAT #GValue.
980  *
981  * Returns: float contents of @value
982  */
983 gfloat
g_value_get_float(const GValue * value)984 g_value_get_float (const GValue *value)
985 {
986   g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (value), 0);
987 
988   return value->data[0].v_float;
989 }
990 
991 /**
992  * g_value_set_double:
993  * @value: a valid #GValue of type %G_TYPE_DOUBLE
994  * @v_double: double value to be set
995  *
996  * Set the contents of a %G_TYPE_DOUBLE #GValue to @v_double.
997  */
998 void
g_value_set_double(GValue * value,gdouble v_double)999 g_value_set_double (GValue *value,
1000 		    gdouble v_double)
1001 {
1002   g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value));
1003 
1004   value->data[0].v_double = v_double;
1005 }
1006 
1007 /**
1008  * g_value_get_double:
1009  * @value: a valid #GValue of type %G_TYPE_DOUBLE
1010  *
1011  * Get the contents of a %G_TYPE_DOUBLE #GValue.
1012  *
1013  * Returns: double contents of @value
1014  */
1015 gdouble
g_value_get_double(const GValue * value)1016 g_value_get_double (const GValue *value)
1017 {
1018   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (value), 0);
1019 
1020   return value->data[0].v_double;
1021 }
1022 
1023 /**
1024  * g_value_set_string:
1025  * @value: a valid #GValue of type %G_TYPE_STRING
1026  * @v_string: (nullable): caller-owned string to be duplicated for the #GValue
1027  *
1028  * Set the contents of a %G_TYPE_STRING #GValue to @v_string.
1029  */
1030 void
g_value_set_string(GValue * value,const gchar * v_string)1031 g_value_set_string (GValue	*value,
1032 		    const gchar *v_string)
1033 {
1034   gchar *new_val;
1035 
1036   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1037 
1038   new_val = g_strdup (v_string);
1039 
1040   if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
1041     value->data[1].v_uint = 0;
1042   else
1043     g_free (value->data[0].v_pointer);
1044 
1045   value->data[0].v_pointer = new_val;
1046 }
1047 
1048 /**
1049  * g_value_set_static_string:
1050  * @value: a valid #GValue of type %G_TYPE_STRING
1051  * @v_string: (nullable): static string to be set
1052  *
1053  * Set the contents of a %G_TYPE_STRING #GValue to @v_string.
1054  * The string is assumed to be static, and is thus not duplicated
1055  * when setting the #GValue.
1056  */
1057 void
g_value_set_static_string(GValue * value,const gchar * v_string)1058 g_value_set_static_string (GValue      *value,
1059 			   const gchar *v_string)
1060 {
1061   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1062 
1063   if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
1064     g_free (value->data[0].v_pointer);
1065   value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
1066   value->data[0].v_pointer = (gchar*) v_string;
1067 }
1068 
1069 /**
1070  * g_value_set_string_take_ownership:
1071  * @value: a valid #GValue of type %G_TYPE_STRING
1072  * @v_string: (nullable): duplicated unowned string to be set
1073  *
1074  * This is an internal function introduced mainly for C marshallers.
1075  *
1076  * Deprecated: 2.4: Use g_value_take_string() instead.
1077  */
1078 void
g_value_set_string_take_ownership(GValue * value,gchar * v_string)1079 g_value_set_string_take_ownership (GValue *value,
1080 				   gchar  *v_string)
1081 {
1082   g_value_take_string (value, v_string);
1083 }
1084 
1085 /**
1086  * g_value_take_string:
1087  * @value: a valid #GValue of type %G_TYPE_STRING
1088  * @v_string: (nullable): string to take ownership of
1089  *
1090  * Sets the contents of a %G_TYPE_STRING #GValue to @v_string.
1091  *
1092  * Since: 2.4
1093  */
1094 void
g_value_take_string(GValue * value,gchar * v_string)1095 g_value_take_string (GValue *value,
1096 		     gchar  *v_string)
1097 {
1098   g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1099 
1100   if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
1101     value->data[1].v_uint = 0;
1102   else
1103     g_free (value->data[0].v_pointer);
1104   value->data[0].v_pointer = v_string;
1105 }
1106 
1107 /**
1108  * g_value_get_string:
1109  * @value: a valid #GValue of type %G_TYPE_STRING
1110  *
1111  * Get the contents of a %G_TYPE_STRING #GValue.
1112  *
1113  * Returns: string content of @value
1114  */
1115 const gchar*
g_value_get_string(const GValue * value)1116 g_value_get_string (const GValue *value)
1117 {
1118   g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
1119 
1120   return value->data[0].v_pointer;
1121 }
1122 
1123 /**
1124  * g_value_dup_string:
1125  * @value: a valid #GValue of type %G_TYPE_STRING
1126  *
1127  * Get a copy the contents of a %G_TYPE_STRING #GValue.
1128  *
1129  * Returns: a newly allocated copy of the string content of @value
1130  */
1131 gchar*
g_value_dup_string(const GValue * value)1132 g_value_dup_string (const GValue *value)
1133 {
1134   g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
1135 
1136   return g_strdup (value->data[0].v_pointer);
1137 }
1138 
1139 /**
1140  * g_value_set_pointer:
1141  * @value: a valid #GValue of %G_TYPE_POINTER
1142  * @v_pointer: pointer value to be set
1143  *
1144  * Set the contents of a pointer #GValue to @v_pointer.
1145  */
1146 void
g_value_set_pointer(GValue * value,gpointer v_pointer)1147 g_value_set_pointer (GValue  *value,
1148 		     gpointer v_pointer)
1149 {
1150   g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
1151 
1152   value->data[0].v_pointer = v_pointer;
1153 }
1154 
1155 /**
1156  * g_value_get_pointer:
1157  * @value: a valid #GValue of %G_TYPE_POINTER
1158  *
1159  * Get the contents of a pointer #GValue.
1160  *
1161  * Returns: (transfer none): pointer contents of @value
1162  */
1163 gpointer
g_value_get_pointer(const GValue * value)1164 g_value_get_pointer (const GValue *value)
1165 {
1166   g_return_val_if_fail (G_VALUE_HOLDS_POINTER (value), NULL);
1167 
1168   return value->data[0].v_pointer;
1169 }
1170 
G_DEFINE_POINTER_TYPE(GType,g_gtype)1171 G_DEFINE_POINTER_TYPE (GType, g_gtype)
1172 
1173 /**
1174  * g_value_set_gtype:
1175  * @value: a valid #GValue of type %G_TYPE_GTYPE
1176  * @v_gtype: #GType to be set
1177  *
1178  * Set the contents of a %G_TYPE_GTYPE #GValue to @v_gtype.
1179  *
1180  * Since: 2.12
1181  */
1182 void
1183 g_value_set_gtype (GValue *value,
1184 		   GType   v_gtype)
1185 {
1186   g_return_if_fail (G_VALUE_HOLDS_GTYPE (value));
1187 
1188   value->data[0].v_pointer = GSIZE_TO_POINTER (v_gtype);
1189 
1190 }
1191 
1192 /**
1193  * g_value_get_gtype:
1194  * @value: a valid #GValue of type %G_TYPE_GTYPE
1195  *
1196  * Get the contents of a %G_TYPE_GTYPE #GValue.
1197  *
1198  * Since: 2.12
1199  *
1200  * Returns: the #GType stored in @value
1201  */
1202 GType
g_value_get_gtype(const GValue * value)1203 g_value_get_gtype (const GValue *value)
1204 {
1205   g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), 0);
1206 
1207   return GPOINTER_TO_SIZE (value->data[0].v_pointer);
1208 }
1209 
1210 /**
1211  * g_value_set_variant:
1212  * @value: a valid #GValue of type %G_TYPE_VARIANT
1213  * @variant: (nullable): a #GVariant, or %NULL
1214  *
1215  * Set the contents of a variant #GValue to @variant.
1216  * If the variant is floating, it is consumed.
1217  *
1218  * Since: 2.26
1219  */
1220 void
g_value_set_variant(GValue * value,GVariant * variant)1221 g_value_set_variant (GValue   *value,
1222                      GVariant *variant)
1223 {
1224   GVariant *old_variant;
1225 
1226   g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
1227 
1228   old_variant = value->data[0].v_pointer;
1229 
1230   if (variant)
1231     value->data[0].v_pointer = g_variant_ref_sink (variant);
1232   else
1233     value->data[0].v_pointer = NULL;
1234 
1235   if (old_variant)
1236     g_variant_unref (old_variant);
1237 }
1238 
1239 /**
1240  * g_value_take_variant:
1241  * @value: a valid #GValue of type %G_TYPE_VARIANT
1242  * @variant: (nullable) (transfer full): a #GVariant, or %NULL
1243  *
1244  * Set the contents of a variant #GValue to @variant, and takes over
1245  * the ownership of the caller's reference to @variant;
1246  * the caller doesn't have to unref it any more (i.e. the reference
1247  * count of the variant is not increased).
1248  *
1249  * If @variant was floating then its floating reference is converted to
1250  * a hard reference.
1251  *
1252  * If you want the #GValue to hold its own reference to @variant, use
1253  * g_value_set_variant() instead.
1254  *
1255  * This is an internal function introduced mainly for C marshallers.
1256  *
1257  * Since: 2.26
1258  */
1259 void
g_value_take_variant(GValue * value,GVariant * variant)1260 g_value_take_variant (GValue   *value,
1261                       GVariant *variant)
1262 {
1263   GVariant *old_variant;
1264 
1265   g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
1266 
1267   old_variant = value->data[0].v_pointer;
1268 
1269   if (variant)
1270     value->data[0].v_pointer = g_variant_take_ref (variant);
1271   else
1272     value->data[0].v_pointer = NULL;
1273 
1274   if (old_variant)
1275     g_variant_unref (old_variant);
1276 }
1277 
1278 /**
1279  * g_value_get_variant:
1280  * @value: a valid #GValue of type %G_TYPE_VARIANT
1281  *
1282  * Get the contents of a variant #GValue.
1283  *
1284  * Returns: (transfer none) (nullable): variant contents of @value (may be %NULL)
1285  *
1286  * Since: 2.26
1287  */
1288 GVariant*
g_value_get_variant(const GValue * value)1289 g_value_get_variant (const GValue *value)
1290 {
1291   g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
1292 
1293   return value->data[0].v_pointer;
1294 }
1295 
1296 /**
1297  * g_value_dup_variant:
1298  * @value: a valid #GValue of type %G_TYPE_VARIANT
1299  *
1300  * Get the contents of a variant #GValue, increasing its refcount. The returned
1301  * #GVariant is never floating.
1302  *
1303  * Returns: (transfer full) (nullable): variant contents of @value (may be %NULL);
1304  *    should be unreffed using g_variant_unref() when no longer needed
1305  *
1306  * Since: 2.26
1307  */
1308 GVariant*
g_value_dup_variant(const GValue * value)1309 g_value_dup_variant (const GValue *value)
1310 {
1311   GVariant *variant;
1312 
1313   g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
1314 
1315   variant = value->data[0].v_pointer;
1316   if (variant)
1317     g_variant_ref_sink (variant);
1318 
1319   return variant;
1320 }
1321 
1322 /**
1323  * g_strdup_value_contents:
1324  * @value: #GValue which contents are to be described.
1325  *
1326  * Return a newly allocated string, which describes the contents of a
1327  * #GValue.  The main purpose of this function is to describe #GValue
1328  * contents for debugging output, the way in which the contents are
1329  * described may change between different GLib versions.
1330  *
1331  * Returns: Newly allocated string.
1332  */
1333 gchar*
g_strdup_value_contents(const GValue * value)1334 g_strdup_value_contents (const GValue *value)
1335 {
1336   const gchar *src;
1337   gchar *contents;
1338 
1339   g_return_val_if_fail (G_IS_VALUE (value), NULL);
1340 
1341   if (G_VALUE_HOLDS_STRING (value))
1342     {
1343       src = g_value_get_string (value);
1344 
1345       if (!src)
1346 	contents = g_strdup ("NULL");
1347       else
1348 	{
1349 	  gchar *s = g_strescape (src, NULL);
1350 
1351 	  contents = g_strdup_printf ("\"%s\"", s);
1352 	  g_free (s);
1353 	}
1354     }
1355   else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
1356     {
1357       GValue tmp_value = G_VALUE_INIT;
1358       gchar *s;
1359 
1360       g_value_init (&tmp_value, G_TYPE_STRING);
1361       g_value_transform (value, &tmp_value);
1362       s = g_strescape (g_value_get_string (&tmp_value), NULL);
1363       g_value_unset (&tmp_value);
1364       if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value))
1365 	contents = g_strdup_printf ("((%s) %s)",
1366 				    g_type_name (G_VALUE_TYPE (value)),
1367 				    s);
1368       else
1369 	contents = g_strdup (s ? s : "NULL");
1370       g_free (s);
1371     }
1372   else if (g_value_fits_pointer (value))
1373     {
1374       gpointer p = g_value_peek_pointer (value);
1375 
1376       if (!p)
1377 	contents = g_strdup ("NULL");
1378       else if (G_VALUE_HOLDS_OBJECT (value))
1379 	contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p);
1380       else if (G_VALUE_HOLDS_PARAM (value))
1381 	contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p);
1382       else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
1383         {
1384           GStrv strv = g_value_get_boxed (value);
1385           GString *tmp = g_string_new ("[");
1386 
1387           while (*strv != NULL)
1388             {
1389               gchar *escaped = g_strescape (*strv, NULL);
1390 
1391               g_string_append_printf (tmp, "\"%s\"", escaped);
1392               g_free (escaped);
1393 
1394               if (*++strv != NULL)
1395                 g_string_append (tmp, ", ");
1396             }
1397 
1398           g_string_append (tmp, "]");
1399           contents = g_string_free (tmp, FALSE);
1400         }
1401       else if (G_VALUE_HOLDS_BOXED (value))
1402 	contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p);
1403       else if (G_VALUE_HOLDS_POINTER (value))
1404 	contents = g_strdup_printf ("((gpointer) %p)", p);
1405       else
1406 	contents = g_strdup ("???");
1407     }
1408   else
1409     contents = g_strdup ("???");
1410 
1411   return contents;
1412 }
1413 
1414 /**
1415  * g_pointer_type_register_static:
1416  * @name: the name of the new pointer type.
1417  *
1418  * Creates a new %G_TYPE_POINTER derived type id for a new
1419  * pointer type with name @name.
1420  *
1421  * Returns: a new %G_TYPE_POINTER derived type id for @name.
1422  */
1423 GType
g_pointer_type_register_static(const gchar * name)1424 g_pointer_type_register_static (const gchar *name)
1425 {
1426   const GTypeInfo type_info = {
1427     0,			/* class_size */
1428     NULL,		/* base_init */
1429     NULL,		/* base_finalize */
1430     NULL,		/* class_init */
1431     NULL,		/* class_finalize */
1432     NULL,		/* class_data */
1433     0,			/* instance_size */
1434     0,			/* n_preallocs */
1435     NULL,		/* instance_init */
1436     NULL		/* value_table */
1437   };
1438   GType type;
1439 
1440   g_return_val_if_fail (name != NULL, 0);
1441   g_return_val_if_fail (g_type_from_name (name) == 0, 0);
1442 
1443   type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0);
1444 
1445   return type;
1446 }
1447