1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
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.
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.
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.
24 #include "gvaluetypes.h"
26 #include "gvaluecollector.h"
28 #include <stdlib.h> /* qsort() */
31 /* --- value functions --- */
33 value_init_long0 (GValue *value)
35 value->data[0].v_long = 0;
39 value_copy_long0 (const GValue *src_value,
42 dest_value->data[0].v_long = src_value->data[0].v_long;
46 value_lcopy_char (const GValue *value,
47 guint n_collect_values,
48 GTypeCValue *collect_values,
51 gint8 *int8_p = collect_values[0].v_pointer;
54 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
56 *int8_p = value->data[0].v_int;
62 value_lcopy_boolean (const GValue *value,
63 guint n_collect_values,
64 GTypeCValue *collect_values,
67 gboolean *bool_p = collect_values[0].v_pointer;
70 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
72 *bool_p = value->data[0].v_int;
78 value_collect_int (GValue *value,
79 guint n_collect_values,
80 GTypeCValue *collect_values,
83 value->data[0].v_int = collect_values[0].v_int;
89 value_lcopy_int (const GValue *value,
90 guint n_collect_values,
91 GTypeCValue *collect_values,
94 gint *int_p = collect_values[0].v_pointer;
97 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
99 *int_p = value->data[0].v_int;
105 value_collect_long (GValue *value,
106 guint n_collect_values,
107 GTypeCValue *collect_values,
110 value->data[0].v_long = collect_values[0].v_long;
116 value_lcopy_long (const GValue *value,
117 guint n_collect_values,
118 GTypeCValue *collect_values,
121 glong *long_p = collect_values[0].v_pointer;
124 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
126 *long_p = value->data[0].v_long;
132 value_init_int64 (GValue *value)
134 value->data[0].v_int64 = 0;
138 value_copy_int64 (const GValue *src_value,
141 dest_value->data[0].v_int64 = src_value->data[0].v_int64;
145 value_collect_int64 (GValue *value,
146 guint n_collect_values,
147 GTypeCValue *collect_values,
150 value->data[0].v_int64 = collect_values[0].v_int64;
156 value_lcopy_int64 (const GValue *value,
157 guint n_collect_values,
158 GTypeCValue *collect_values,
161 gint64 *int64_p = collect_values[0].v_pointer;
164 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
166 *int64_p = value->data[0].v_int64;
172 value_init_float (GValue *value)
174 value->data[0].v_float = 0.0;
178 value_copy_float (const GValue *src_value,
181 dest_value->data[0].v_float = src_value->data[0].v_float;
185 value_collect_float (GValue *value,
186 guint n_collect_values,
187 GTypeCValue *collect_values,
190 value->data[0].v_float = collect_values[0].v_double;
196 value_lcopy_float (const GValue *value,
197 guint n_collect_values,
198 GTypeCValue *collect_values,
201 gfloat *float_p = collect_values[0].v_pointer;
204 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
206 *float_p = value->data[0].v_float;
212 value_init_double (GValue *value)
214 value->data[0].v_double = 0.0;
218 value_copy_double (const GValue *src_value,
221 dest_value->data[0].v_double = src_value->data[0].v_double;
225 value_collect_double (GValue *value,
226 guint n_collect_values,
227 GTypeCValue *collect_values,
230 value->data[0].v_double = collect_values[0].v_double;
236 value_lcopy_double (const GValue *value,
237 guint n_collect_values,
238 GTypeCValue *collect_values,
241 gdouble *double_p = collect_values[0].v_pointer;
244 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
246 *double_p = value->data[0].v_double;
252 value_init_string (GValue *value)
254 value->data[0].v_pointer = NULL;
258 value_free_string (GValue *value)
260 if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
261 g_free (value->data[0].v_pointer);
265 value_copy_string (const GValue *src_value,
268 dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
272 value_collect_string (GValue *value,
273 guint n_collect_values,
274 GTypeCValue *collect_values,
277 if (!collect_values[0].v_pointer)
278 value->data[0].v_pointer = NULL;
279 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
281 value->data[0].v_pointer = collect_values[0].v_pointer;
282 value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
285 value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
291 value_lcopy_string (const GValue *value,
292 guint n_collect_values,
293 GTypeCValue *collect_values,
296 gchar **string_p = collect_values[0].v_pointer;
299 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
301 if (!value->data[0].v_pointer)
303 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
304 *string_p = value->data[0].v_pointer;
306 *string_p = g_strdup (value->data[0].v_pointer);
312 value_init_pointer (GValue *value)
314 value->data[0].v_pointer = NULL;
318 value_copy_pointer (const GValue *src_value,
321 dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
325 value_peek_pointer0 (const GValue *value)
327 return value->data[0].v_pointer;
331 value_collect_pointer (GValue *value,
332 guint n_collect_values,
333 GTypeCValue *collect_values,
336 value->data[0].v_pointer = collect_values[0].v_pointer;
342 value_lcopy_pointer (const GValue *value,
343 guint n_collect_values,
344 GTypeCValue *collect_values,
347 gpointer *pointer_p = collect_values[0].v_pointer;
350 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
352 *pointer_p = value->data[0].v_pointer;
358 /* --- type initialization --- */
360 g_value_types_init (void) /* sync with gtype.c */
364 NULL, /* base_init */
365 NULL, /* base_destroy */
366 NULL, /* class_init */
367 NULL, /* class_destroy */
368 NULL, /* class_data */
369 0, /* instance_size */
371 NULL, /* instance_init */
372 NULL, /* value_table */
374 const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
377 /* G_TYPE_CHAR / G_TYPE_UCHAR
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 */
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);
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 */
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);
415 /* G_TYPE_INT / G_TYPE_UINT
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 */
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);
435 /* G_TYPE_LONG / G_TYPE_ULONG
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 */
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);
455 /* G_TYPE_INT64 / G_TYPE_UINT64
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 */
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);
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 */
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);
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 */
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);
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 */
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);
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 */
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);
549 /* --- GValue functions --- */
551 g_value_set_char (GValue *value,
554 g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
556 value->data[0].v_int = v_char;
560 g_value_get_char (const GValue *value)
562 g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
564 return value->data[0].v_int;
568 g_value_set_uchar (GValue *value,
571 g_return_if_fail (G_VALUE_HOLDS_UCHAR (value));
573 value->data[0].v_uint = v_uchar;
577 g_value_get_uchar (const GValue *value)
579 g_return_val_if_fail (G_VALUE_HOLDS_UCHAR (value), 0);
581 return value->data[0].v_uint;
585 g_value_set_boolean (GValue *value,
588 g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
590 value->data[0].v_int = v_boolean != FALSE;
594 g_value_get_boolean (const GValue *value)
596 g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (value), 0);
598 return value->data[0].v_int;
602 g_value_set_int (GValue *value,
605 g_return_if_fail (G_VALUE_HOLDS_INT (value));
607 value->data[0].v_int = v_int;
611 g_value_get_int (const GValue *value)
613 g_return_val_if_fail (G_VALUE_HOLDS_INT (value), 0);
615 return value->data[0].v_int;
619 g_value_set_uint (GValue *value,
622 g_return_if_fail (G_VALUE_HOLDS_UINT (value));
624 value->data[0].v_uint = v_uint;
628 g_value_get_uint (const GValue *value)
630 g_return_val_if_fail (G_VALUE_HOLDS_UINT (value), 0);
632 return value->data[0].v_uint;
636 g_value_set_long (GValue *value,
639 g_return_if_fail (G_VALUE_HOLDS_LONG (value));
641 value->data[0].v_long = v_long;
645 g_value_get_long (const GValue *value)
647 g_return_val_if_fail (G_VALUE_HOLDS_LONG (value), 0);
649 return value->data[0].v_long;
653 g_value_set_ulong (GValue *value,
656 g_return_if_fail (G_VALUE_HOLDS_ULONG (value));
658 value->data[0].v_ulong = v_ulong;
662 g_value_get_ulong (const GValue *value)
664 g_return_val_if_fail (G_VALUE_HOLDS_ULONG (value), 0);
666 return value->data[0].v_ulong;
670 g_value_set_int64 (GValue *value,
673 g_return_if_fail (G_VALUE_HOLDS_INT64 (value));
675 value->data[0].v_int64 = v_int64;
679 g_value_get_int64 (const GValue *value)
681 g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0);
683 return value->data[0].v_int64;
687 g_value_set_uint64 (GValue *value,
690 g_return_if_fail (G_VALUE_HOLDS_UINT64 (value));
692 value->data[0].v_uint64 = v_uint64;
696 g_value_get_uint64 (const GValue *value)
698 g_return_val_if_fail (G_VALUE_HOLDS_UINT64 (value), 0);
700 return value->data[0].v_uint64;
704 g_value_set_float (GValue *value,
707 g_return_if_fail (G_VALUE_HOLDS_FLOAT (value));
709 value->data[0].v_float = v_float;
713 g_value_get_float (const GValue *value)
715 g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (value), 0);
717 return value->data[0].v_float;
721 g_value_set_double (GValue *value,
724 g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value));
726 value->data[0].v_double = v_double;
730 g_value_get_double (const GValue *value)
732 g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (value), 0);
734 return value->data[0].v_double;
738 g_value_set_string (GValue *value,
739 const gchar *v_string)
741 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
743 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
744 value->data[1].v_uint = 0;
746 g_free (value->data[0].v_pointer);
747 value->data[0].v_pointer = g_strdup (v_string);
751 g_value_set_static_string (GValue *value,
752 const gchar *v_string)
754 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
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;
763 g_value_set_string_take_ownership (GValue *value,
766 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
768 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
769 value->data[1].v_uint = 0;
771 g_free (value->data[0].v_pointer);
772 value->data[0].v_pointer = v_string;
775 G_CONST_RETURN gchar*
776 g_value_get_string (const GValue *value)
778 g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
780 return value->data[0].v_pointer;
784 g_value_dup_string (const GValue *value)
786 g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
788 return g_strdup (value->data[0].v_pointer);
792 g_value_set_pointer (GValue *value,
795 g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
797 value->data[0].v_pointer = v_pointer;
801 g_value_get_pointer (const GValue *value)
803 g_return_val_if_fail (G_VALUE_HOLDS_POINTER (value), NULL);
805 return value->data[0].v_pointer;
808 /* need extra includes for g_strdup_value_contents() ;( */
815 g_strdup_value_contents (const GValue *value)
820 g_return_val_if_fail (G_IS_VALUE (value), NULL);
822 if (G_VALUE_HOLDS_STRING (value))
824 src = g_value_get_string (value);
827 contents = g_strdup ("NULL");
830 gchar *s = g_strescape (src, NULL);
832 contents = g_strdup_printf ("\"%s\"", s);
836 else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
838 GValue tmp_value = { 0, };
841 g_value_init (&tmp_value, G_TYPE_STRING);
842 g_value_transform (value, &tmp_value);
843 s = g_strescape (g_value_get_string (&tmp_value), NULL);
844 g_value_unset (&tmp_value);
845 if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value))
846 contents = g_strdup_printf ("((%s) %s)",
847 g_type_name (G_VALUE_TYPE (value)),
850 contents = g_strdup (s ? s : "NULL");
853 else if (g_value_fits_pointer (value))
855 gpointer p = g_value_peek_pointer (value);
858 contents = g_strdup ("NULL");
859 else if (G_VALUE_HOLDS_OBJECT (value))
860 contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p);
861 else if (G_VALUE_HOLDS_PARAM (value))
862 contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p);
863 else if (G_VALUE_HOLDS_BOXED (value))
864 contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p);
865 else if (G_VALUE_HOLDS_POINTER (value))
866 contents = g_strdup_printf ("((gpointer) %p)", p);
868 contents = g_strdup ("???");
871 contents = g_strdup ("???");
877 g_pointer_type_register_static (const gchar *name)
879 static const GTypeInfo type_info = {
881 NULL, /* base_init */
882 NULL, /* base_finalize */
883 NULL, /* class_init */
884 NULL, /* class_finalize */
885 NULL, /* class_data */
886 0, /* instance_size */
888 NULL, /* instance_init */
889 NULL /* value_table */
893 g_return_val_if_fail (name != NULL, 0);
894 g_return_val_if_fail (g_type_from_name (name) == 0, 0);
896 type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0);