define gstring in terms of gchar*. this typedef reflects the type name of

Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>

        * glib.h: define gstring in terms of gchar*. this typedef reflects
        the type name of the primitive G_TYPE_STRING in the gobject module.

Sat Jun 24 23:03:04 2000  Tim Janik  <timj@gtk.org>

        * gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN,
        G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT,
        G_TYPE_DOUBLE and G_TYPE_STRING fundamental types.
        added a GTypeValueTable* pointer to GTypeInfo structure for types
        to implement GValue handling functions.
        GTypeValueTable contains the following members:
          value_init(): initialize a GValue structure.
          value_free(): free GValue structure contents (optional).
          value_copy(): copy one GValue contents to another GValue structure of
          collect_type: varargs collection type for the first variable argument
          to be collected by collect_value().
          collect_value(): variable arguments collection function (optional).
          lcopy_type: varargs collection type for the first variable argument
          to be location copyied by lcopy_value().
          lcopy_value(): variable arguments location copy function (optional).
        g_type_value_table_peek(): new function to retrive the GTypeValueTable*
        for a type node. ValueTables get inherited from parent types, unless
        overridden through the GTypeInfo structure. internally, GTypeValueTable
        support means an added overhead of one pointer per static or used
        dynamic type node.
        g_type_add_class_cache_func(): provide a cache_func/data pair to be
        called  prior to a type nodes last_unref() function, this can be used
        to prevent premature class destruction. multiple installed cache_func()
        will be chained upon last_unref() untill one of them returns TRUE.
        the cache_func()s have to check the type id passed in to figure whether
        they actually wants to cache the class of this type (since any types are
        routed through the cache_func() chain).
        g_type_remove_class_cache_func(): remove a previously installed
        cache_func/data pair. the cache maintained by this function has to be
        clear when calling g_type_remove_class_cache_func() to avoid leaks.
        g_type_class_unref_uncached(): class unref function for cache_func()
        implementations, unreferences a class omitting the cache chain (and
        therefore unref->cache->unref->... loops).

        * gvaluetypes.[hc]: provide the value setters/getters for the primitive
        fundamental types boolean, char, uchar, int, uint, long, ulong, float,
        double and string.

        * gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a
        GTypeValueTable is provided for this type.
        removed g_value_init_default(), g_value_validate(), g_value_defaults(),
        g_value_set_default() and g_values_cmp() as these are supplied by the
        GParamSpec API now.
        moved g_values_exchange() into the "implementation details" section,
        since it just provides the underlying functionality for
        g_value_convert().

        * gvaluecollector.h: renamed the varargs value container from
        GParamCValue to GTypeCValue as the value collection methods are
        supplied by the type system now.
        G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to
        G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a
        GParamSpec structure now.

        * genums.h: macros cleanups/fixes.

        * genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type
        and assorted g_value_{s|g}et_{enum|flags}() implementations.

        * gobject.[hc]:
        provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods
        and g_value_{s|g}et_object().

        * gparam.[hc]: reduced class to value_set_default(),
        value_validate() and values_cmp(). also parameters now need to fill
        in a GType value_type; field to indicate the GValue type they
        are handling. provide g_param_value_set_default(),
        g_param_value_defaults(), g_param_value_validate() and
        g_param_values_cmp().

        * gparamspecs.[hc]: got rid of the g_value_* functions and
        the G_IS_VALUE_* macros. adapted param spec implementations
        according to the GParamSpecClass changes.
This commit is contained in:
Tim Janik
2000-06-24 22:30:10 +00:00
committed by Tim Janik
parent 0891c64816
commit 09f8e937f2
29 changed files with 1996 additions and 1526 deletions

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -1,3 +1,8 @@
Fri Jun 23 17:20:26 2000 Tim Janik <timj@gtk.org>
* glib.h: define gstring in terms of gchar*. this typedef reflects
the type name of the primitive G_TYPE_STRING in the gobject module.
Wed Jun 21 12:09:03 2000 Owen Taylor <otaylor@redhat.com>
* gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h

View File

@@ -23,6 +23,7 @@
#include <gobject/gtype.h>
#include <gobject/genums.h>
#include <gobject/gvalue.h>
#include <gobject/gvaluetypes.h>
#include <gobject/gparam.h>
#include <gobject/gparamspecs.h>
#include <gobject/gobject.h>

1
glib.h
View File

@@ -500,6 +500,7 @@ typedef short gshort;
typedef long glong;
typedef int gint;
typedef gint gboolean;
typedef gchar* gstring;
typedef unsigned char guchar;
typedef unsigned short gushort;

View File

@@ -23,6 +23,7 @@
#include <gobject/gtype.h>
#include <gobject/genums.h>
#include <gobject/gvalue.h>
#include <gobject/gvaluetypes.h>
#include <gobject/gparam.h>
#include <gobject/gparamspecs.h>
#include <gobject/gobject.h>

View File

@@ -500,6 +500,7 @@ typedef short gshort;
typedef long glong;
typedef int gint;
typedef gint gboolean;
typedef gchar* gstring;
typedef unsigned char guchar;
typedef unsigned short gushort;

View File

@@ -1,3 +1,79 @@
Sat Jun 24 23:03:04 2000 Tim Janik <timj@gtk.org>
* gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN,
G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT,
G_TYPE_DOUBLE and G_TYPE_STRING fundamental types.
added a GTypeValueTable* pointer to GTypeInfo structure for types
to implement GValue handling functions.
GTypeValueTable contains the following members:
value_init(): initialize a GValue structure.
value_free(): free GValue structure contents (optional).
value_copy(): copy one GValue contents to another GValue structure of
collect_type: varargs collection type for the first variable argument
to be collected by collect_value().
collect_value(): variable arguments collection function (optional).
lcopy_type: varargs collection type for the first variable argument
to be location copyied by lcopy_value().
lcopy_value(): variable arguments location copy function (optional).
g_type_value_table_peek(): new function to retrive the GTypeValueTable*
for a type node. ValueTables get inherited from parent types, unless
overridden through the GTypeInfo structure. internally, GTypeValueTable
support means an added overhead of one pointer per static or used
dynamic type node.
g_type_add_class_cache_func(): provide a cache_func/data pair to be
called prior to a type nodes last_unref() function, this can be used
to prevent premature class destruction. multiple installed cache_func()
will be chained upon last_unref() untill one of them returns TRUE.
the cache_func()s have to check the type id passed in to figure whether
they actually wants to cache the class of this type (since any types are
routed through the cache_func() chain).
g_type_remove_class_cache_func(): remove a previously installed
cache_func/data pair. the cache maintained by this function has to be
clear when calling g_type_remove_class_cache_func() to avoid leaks.
g_type_class_unref_uncached(): class unref function for cache_func()
implementations, unreferences a class omitting the cache chain (and
therefore unref->cache->unref->... loops).
* gvaluetypes.[hc]: provide the value setters/getters for the primitive
fundamental types boolean, char, uchar, int, uint, long, ulong, float,
double and string.
* gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a
GTypeValueTable is provided for this type.
removed g_value_init_default(), g_value_validate(), g_value_defaults(),
g_value_set_default() and g_values_cmp() as these are supplied by the
GParamSpec API now.
moved g_values_exchange() into the "implementation details" section,
since it just provides the underlying functionality for
g_value_convert().
* gvaluecollector.h: renamed the varargs value container from
GParamCValue to GTypeCValue as the value collection methods are
supplied by the type system now.
G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to
G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a
GParamSpec structure now.
* genums.h: macros cleanups/fixes.
* genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type
and assorted g_value_{s|g}et_{enum|flags}() implementations.
* gobject.[hc]:
provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods
and g_value_{s|g}et_object().
* gparam.[hc]: reduced class to value_set_default(),
value_validate() and values_cmp(). also parameters now need to fill
in a GType value_type; field to indicate the GValue type they
are handling. provide g_param_value_set_default(),
g_param_value_defaults(), g_param_value_validate() and
g_param_values_cmp().
* gparamspecs.[hc]: got rid of the g_value_* functions and
the G_IS_VALUE_* macros. adapted param spec implementations
according to the GParamSpecClass changes.
Sat Jun 10 08:38:27 2000 Tim Janik <timj@gtk.org>
* gtype.c (type_class_init): fetch the nth iface entry of the

View File

@@ -28,6 +28,7 @@ libgobject_la_LIBADD = # $(libglib)
# GObject header files for public installation (non-generated)
gobject_public_h_sources = @STRIP_BEGIN@ \
gvalue.h \
gvaluetypes.h \
gparam.h \
gparamspecs.h \
genums.h \
@@ -42,6 +43,7 @@ gobject_private_h_sources = @STRIP_BEGIN@ \
# GObject C sources to build the library from
gobject_c_sources = @STRIP_BEGIN@ \
gvalue.c \
gvaluetypes.c \
gparam.c \
gparamspecs.c \
genums.c \

View File

@@ -18,24 +18,35 @@
*/
#include "genums.h"
#include "gvalue.h"
#include "gvaluecollector.h"
/* --- prototypes --- */
extern void g_enum_types_init (void);
static void g_enum_class_init (GEnumClass *class,
gpointer class_data);
static void g_flags_class_init (GFlagsClass *class,
gpointer class_data);
static void g_value_enum_init (GValue *value);
static void g_value_enum_copy_value (const GValue *src_value,
GValue *dest_value);
static gchar* g_value_enum_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
static gchar* g_value_enum_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
/* --- functions --- */
void
g_enum_types_init (void) /* sync with glib-gtype.c */
g_enum_types_init (void) /* sync with gtype.c */
{
static gboolean initialized = FALSE;
static const GTypeFundamentalInfo finfo = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static GTypeInfo info = {
0 /* class_size */,
@@ -45,21 +56,32 @@ g_enum_types_init (void) /* sync with glib-gtype.c */
NULL /* class_finalize */,
NULL /* class_data */,
};
static const GTypeValueTable value_table = {
g_value_enum_init, /* value_init */
NULL, /* value_free */
g_value_enum_copy_value, /* value_copy */
G_VALUE_COLLECT_INT, /* collect_type */
g_value_enum_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
g_value_enum_lcopy_value, /* lcopy_value */
};
GType type;
g_return_if_fail (initialized == FALSE);
initialized = TRUE;
info.value_table = &value_table;
/* G_TYPE_ENUM
*/
info.class_size = sizeof (GEnumClass);
type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &finfo, &info);
type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &info, &finfo);
g_assert (type == G_TYPE_ENUM);
/* G_TYPE_FLAGS
*/
info.class_size = sizeof (GFlagsClass);
type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &finfo, &info);
type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &info, &finfo);
g_assert (type == G_TYPE_FLAGS);
}
@@ -304,3 +326,79 @@ g_flags_get_first_value (GFlagsClass *flags_class,
return NULL;
}
void
g_value_set_enum (GValue *value,
gint v_enum)
{
g_return_if_fail (G_IS_VALUE_ENUM (value));
value->data[0].v_long = v_enum;
}
gint
g_value_get_enum (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0);
return value->data[0].v_long;
}
void
g_value_set_flags (GValue *value,
guint v_flags)
{
g_return_if_fail (G_IS_VALUE_FLAGS (value));
value->data[0].v_ulong = v_flags;
}
guint
g_value_get_flags (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0);
return value->data[0].v_ulong;
}
static void
g_value_enum_init (GValue *value)
{
value->data[0].v_long = 0;
}
static void
g_value_enum_copy_value (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_long = src_value->data[0].v_long;
}
static gchar*
g_value_enum_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_long = collect_value->v_int;
*collect_type = 0;
return NULL;
}
static gchar*
g_value_enum_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gint *int_p = collect_value->v_pointer;
if (!int_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int_p = value->data[0].v_long;
*collect_type = 0;
return NULL;
}

View File

@@ -28,16 +28,18 @@ extern "C" {
/* --- type macros --- */
#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM)
#define G_ENUM_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_ENUM_NAME(class) (g_type_name (G_ENUM_TYPE (class)))
#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass))
#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM))
#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS)
#define G_FLAGS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_FLAGS_NAME(class) (g_type_name (G_FLAGS_TYPE (class)))
#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass))
#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS))
#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM)
#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass))
#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM))
#define G_ENUM_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_ENUM_CLASS_TYPE_NAME(class) (g_type_name (G_ENUM_TYPE (class)))
#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS)
#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass))
#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS))
#define G_FLAGS_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_FLAGS_CLASS_TYPE_NAME(class) (g_type_name (G_FLAGS_TYPE (class)))
#define G_IS_VALUE_ENUM(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ENUM))
#define G_IS_VALUE_FLAGS(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLAGS))
/* --- enum/flag values & classes --- */
@@ -89,6 +91,13 @@ GFlagsValue* g_flags_get_value_by_name (GFlagsClass *flags_class,
const gchar *name);
GFlagsValue* g_flags_get_value_by_nick (GFlagsClass *flags_class,
const gchar *nick);
void g_value_set_enum (GValue *value,
gint v_enum);
gint g_value_get_enum (GValue *value);
void g_value_set_flags (GValue *value,
guint v_flags);
guint g_value_get_flags (GValue *value);
/* --- registration functions --- */

View File

@@ -19,7 +19,6 @@
#include "gobject.h"
#include "gvalue.h"
#include "gvaluecollector.h"
@@ -31,18 +30,29 @@
/* --- prototypes --- */
extern void g_object_type_init (void);
static void g_object_base_class_init (GObjectClass *class);
static void g_object_base_class_finalize (GObjectClass *class);
static void g_object_do_class_init (GObjectClass *class);
static void g_object_do_init (GObject *object);
static void g_object_do_queue_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_do_dispatch_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_do_queue_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_do_dispatch_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_last_unref (GObject *object);
static void g_object_do_shutdown (GObject *object);
static void g_object_do_finalize (GObject *object);
static void g_value_object_init (GValue *value);
static void g_value_object_free_value (GValue *value);
static void g_value_object_copy_value (const GValue *src_value,
GValue *dest_value);
static gchar* g_value_object_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
static gchar* g_value_object_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
/* --- variables --- */
@@ -61,7 +71,7 @@ debug_objects_foreach (gpointer key,
gpointer user_data)
{
GObject *object = value;
g_message ("[%p] stale %s\tref_count=%u",
object,
G_OBJECT_TYPE_NAME (object),
@@ -79,13 +89,11 @@ debug_objects_atexit (void)
#endif DEBUG_OBJECTS
void
g_object_type_init (void) /* sync with glib-gtype.c */
g_object_type_init (void) /* sync with gtype.c */
{
static gboolean initialized = FALSE;
static const GTypeFundamentalInfo finfo = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static GTypeInfo info = {
sizeof (GObjectClass),
@@ -97,6 +105,16 @@ g_object_type_init (void) /* sync with glib-gtype.c */
sizeof (GObject),
0 /* n_preallocs */,
(GInstanceInitFunc) g_object_do_init,
NULL, /* value_table */
};
static const GTypeValueTable value_table = {
g_value_object_init, /* value_init */
g_value_object_free_value, /* value_free */
g_value_object_copy_value, /* value_copy */
G_VALUE_COLLECT_POINTER, /* collect_type */
g_value_object_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
g_value_object_lcopy_value, /* lcopy_value */
};
GType type;
@@ -105,12 +123,13 @@ g_object_type_init (void) /* sync with glib-gtype.c */
/* G_TYPE_OBJECT
*/
type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &finfo, &info);
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo);
g_assert (type == G_TYPE_OBJECT);
#ifdef DEBUG_OBJECTS
#ifdef DEBUG_OBJECTS
g_atexit (debug_objects_atexit);
#endif DEBUG_OBJECTS
#endif DEBUG_OBJECTS
}
static void
@@ -127,7 +146,7 @@ static void
g_object_base_class_finalize (GObjectClass *class)
{
guint i;
g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
for (i = 0; i < class->n_param_specs; i++)
@@ -158,11 +177,11 @@ g_object_do_class_init (GObjectClass *class)
void
g_object_class_install_param (GObjectClass *class,
guint param_id,
guint param_id,
GParamSpec *pspec /* 1 ref_count taken over */)
{
guint i;
g_return_if_fail (G_IS_OBJECT_CLASS (class));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
if (pspec->flags & G_PARAM_WRITABLE)
@@ -171,7 +190,7 @@ g_object_class_install_param (GObjectClass *class,
g_return_if_fail (class->get_param != NULL);
g_return_if_fail (param_id > 0);
g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
/* expensive paranoia checks ;( */
for (i = 0; i < class->n_param_specs; i++)
if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id)
@@ -191,7 +210,7 @@ g_object_class_install_param (GObjectClass *class,
pspec->name);
return;
}
g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id));
g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class));
i = class->n_param_specs++;
@@ -205,7 +224,7 @@ g_object_class_find_param_spec (GObjectClass *class,
{
g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
g_return_val_if_fail (param_name != NULL, NULL);
return g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_CLASS_TYPE (class),
@@ -217,7 +236,7 @@ g_object_do_init (GObject *object)
{
object->ref_count = 1;
object->qdata = NULL;
#ifdef DEBUG_OBJECTS
if (!debug_objects_ht)
debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
@@ -230,12 +249,12 @@ static void
g_object_last_unref (GObject *object)
{
g_return_if_fail (object->ref_count > 0);
if (object->ref_count == 1) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->shutdown (object);
object->ref_count -= 1;
if (object->ref_count == 0) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->finalize (object);
}
@@ -265,31 +284,31 @@ g_object_do_finalize (GObject *object)
}
gpointer
g_object_new (GType object_type,
g_object_new (GType object_type,
const gchar *first_param_name,
...)
{
GObject *object;
va_list var_args;
g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
va_start (var_args, first_param_name);
object = g_object_new_valist (object_type, first_param_name, var_args);
va_end (var_args);
return object;
}
gpointer
g_object_new_valist (GType object_type,
g_object_new_valist (GType object_type,
const gchar *first_param_name,
va_list var_args)
va_list var_args)
{
GObject *object;
g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
object = (GObject*) g_type_create_instance (object_type);
if (first_param_name)
g_object_set_valist (object, first_param_name, var_args);
@@ -312,15 +331,15 @@ notify_param_changed_handler (gpointer data)
GObject *object;
GObjectClass *class;
GSList *slist;
/* FIXME: need GDK_THREADS lock */
object = G_OBJECT (data);
class = G_OBJECT_GET_CLASS (object);
slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
/* a reference count is still being held */
for (; slist; slist = slist->next)
if (slist->data)
{
@@ -376,11 +395,11 @@ object_get_param (GObject *object,
const gchar *trailer)
{
GObjectClass *class;
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
class = g_type_class_peek (pspec->owner_type);
class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
}
@@ -391,36 +410,36 @@ object_set_param (GObject *object,
const gchar *trailer)
{
GObjectClass *class;
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
class = g_type_class_peek (pspec->owner_type);
class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
class->queue_param_changed (object, pspec);
}
void
g_object_set_valist (GObject *object,
g_object_set_valist (GObject *object,
const gchar *first_param_name,
va_list var_args)
va_list var_args)
{
const gchar *name;
g_return_if_fail (G_IS_OBJECT (object));
g_object_ref (object);
name = first_param_name;
while (name)
{
const gchar *trailer = NULL;
GValue value = { 0, };
GParamSpec *pspec;
gchar *error = NULL;
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
name,
G_OBJECT_TYPE (object),
@@ -442,10 +461,10 @@ g_object_set_valist (GObject *object,
G_OBJECT_TYPE_NAME (object));
break;
}
g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
G_PARAM_COLLECT_VALUE (&value, pspec, var_args, &error);
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
G_VALUE_COLLECT (&value, var_args, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
@@ -456,37 +475,37 @@ g_object_set_valist (GObject *object,
*/
break;
}
object_set_param (object, &value, pspec, trailer);
g_value_unset (&value);
name = va_arg (var_args, gchar*);
}
g_object_unref (object);
}
void
g_object_get_valist (GObject *object,
g_object_get_valist (GObject *object,
const gchar *first_param_name,
va_list var_args)
va_list var_args)
{
const gchar *name;
g_return_if_fail (G_IS_OBJECT (object));
g_object_ref (object);
name = first_param_name;
while (name)
{
const gchar *trailer = NULL;
GValue value = { 0, };
GParamSpec *pspec;
gchar *error = NULL;
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
name,
G_OBJECT_TYPE (object),
@@ -508,12 +527,12 @@ g_object_get_valist (GObject *object,
G_OBJECT_TYPE_NAME (object));
break;
}
g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
object_get_param (object, &value, pspec, trailer);
G_PARAM_LCOPY_VALUE (&value, pspec, var_args, &error);
G_VALUE_LCOPY (&value, var_args, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
@@ -526,55 +545,55 @@ g_object_get_valist (GObject *object,
}
g_value_unset (&value);
name = va_arg (var_args, gchar*);
}
g_object_unref (object);
}
void
g_object_set (GObject *object,
g_object_set (GObject *object,
const gchar *first_param_name,
...)
{
va_list var_args;
g_return_if_fail (G_IS_OBJECT (object));
va_start (var_args, first_param_name);
g_object_set_valist (object, first_param_name, var_args);
va_end (var_args);
}
void
g_object_get (GObject *object,
g_object_get (GObject *object,
const gchar *first_param_name,
...)
{
va_list var_args;
g_return_if_fail (G_IS_OBJECT (object));
va_start (var_args, first_param_name);
g_object_get_valist (object, first_param_name, var_args);
va_end (var_args);
}
void
g_object_set_param (GObject *object,
const gchar *param_name,
g_object_set_param (GObject *object,
const gchar *param_name,
const GValue *value)
{
GParamSpec *pspec;
const gchar *trailer;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (param_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
g_object_ref (object);
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_TYPE (object),
@@ -588,17 +607,17 @@ g_object_set_param (GObject *object,
else
{
GValue tmp_value = { 0, };
/* provide a copy to work from and convert if necessary */
g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec));
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (!g_value_convert (value, &tmp_value) ||
g_value_validate (&tmp_value, pspec))
g_warning ("%s: can't convert `%s' value to parameter `%s' of type `%s'",
g_param_value_validate (pspec, &tmp_value))
g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'",
G_STRLOC,
G_VALUE_TYPE_NAME (value),
pspec->name,
G_PARAM_SPEC_TYPE_NAME (pspec));
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
else
object_set_param (object, &tmp_value, pspec, trailer);
@@ -609,9 +628,9 @@ g_object_set_param (GObject *object,
}
void
g_object_get_param (GObject *object,
g_object_get_param (GObject *object,
const gchar *param_name,
GValue *value)
GValue *value)
{
GParamSpec *pspec;
const gchar *trailer;
@@ -642,13 +661,13 @@ g_object_get_param (GObject *object,
* (though, at this point, GValue should exclusively be modified
* through the accessor functions anyways)
*/
g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec));
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_TYPE (pspec)))
g_warning ("%s: can't retrive parameter `%s' of type `%s' as value of type `%s'",
if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'",
G_STRLOC,
pspec->name,
G_PARAM_SPEC_TYPE_NAME (pspec),
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
G_VALUE_TYPE_NAME (value));
else
{
@@ -664,14 +683,14 @@ g_object_get_param (GObject *object,
}
void
g_object_queue_param_changed (GObject *object,
g_object_queue_param_changed (GObject *object,
const gchar *param_name)
{
GParamSpec *pspec;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (param_name != NULL);
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_TYPE (object),
@@ -690,9 +709,9 @@ g_object_ref (GObject *object)
{
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (object->ref_count > 0, NULL);
object->ref_count += 1;
return object;
}
@@ -701,7 +720,7 @@ g_object_unref (GObject *object)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (object->ref_count > 0);
if (object->ref_count > 1)
object->ref_count -= 1;
else
@@ -713,7 +732,7 @@ g_object_get_qdata (GObject *object,
GQuark quark)
{
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
}
@@ -730,8 +749,8 @@ g_object_set_qdata (GObject *object,
void
g_object_set_qdata_full (GObject *object,
GQuark quark,
gpointer data,
GQuark quark,
gpointer data,
GDestroyNotify destroy)
{
g_return_if_fail (G_IS_OBJECT (object));
@@ -749,3 +768,105 @@ g_object_steal_qdata (GObject *object,
return g_datalist_id_remove_no_notify (&object->qdata, quark);
}
static void
g_value_object_init (GValue *value)
{
value->data[0].v_pointer = NULL;
}
static void
g_value_object_free_value (GValue *value)
{
if (value->data[0].v_pointer)
g_object_unref (value->data[0].v_pointer);
}
static void
g_value_object_copy_value (const GValue *src_value,
GValue *dest_value)
{
if (src_value->data[0].v_pointer)
dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
else
dest_value->data[0].v_pointer = NULL;
}
static gchar*
g_value_object_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
if (collect_value->v_pointer)
{
GObject *object = collect_value->v_pointer;
if (object->g_type_instance.g_class == NULL)
return g_strconcat ("invalid unclassed object pointer for value type `",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
return g_strconcat ("invalid object type `",
G_OBJECT_TYPE_NAME (object),
"' for value type `",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
value->data[0].v_pointer = g_object_ref (object);
}
else
value->data[0].v_pointer = NULL;
*collect_type = 0;
return NULL;
}
static gchar*
g_value_object_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
GObject **object_p = collect_value->v_pointer;
if (!object_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
*collect_type = 0;
return NULL;
}
void
g_value_set_object (GValue *value,
GObject *v_object)
{
g_return_if_fail (G_IS_VALUE_OBJECT (value));
if (v_object)
g_return_if_fail (G_IS_OBJECT (v_object));
if (value->data[0].v_pointer)
g_object_unref (value->data[0].v_pointer);
value->data[0].v_pointer = v_object;
if (value->data[0].v_pointer)
g_object_ref (value->data[0].v_pointer);
}
GObject*
g_value_get_object (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
return value->data[0].v_pointer;
}
GObject*
g_value_dup_object (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
}

View File

@@ -20,6 +20,7 @@
#define __G_GOBJECT_H__
#include <gobject/gtype.h>
#include <gobject/gvalue.h>
#include <gobject/gparam.h>
@@ -43,6 +44,7 @@ extern "C" {
#define G_OBJECT_TYPE_NAME(object) (g_type_name (G_OBJECT_TYPE (object)))
#define G_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class)))
#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_OBJECT))
#define G_NOTIFY_PRIORITY (G_PRIORITY_HIGH_IDLE + 20)
@@ -140,6 +142,10 @@ void g_object_set_qdata_full (GObject *object,
GDestroyNotify destroy);
gpointer g_object_steal_qdata (GObject *object,
GQuark quark);
void g_value_set_object (GValue *value,
GObject *v_object);
GObject* g_value_get_object (GValue *value);
GObject* g_value_dup_object (GValue *value);
/* --- implementation macros --- */

View File

@@ -28,8 +28,6 @@
/* --- prototypes --- */
extern void g_param_types_init (void);
extern void g_param_spec_types_init (void); /* sync with glib-gparamspecs.c */
static void g_param_spec_class_base_init (GParamSpecClass *class);
static void g_param_spec_class_base_finalize (GParamSpecClass *class);
static void g_param_spec_class_init (GParamSpecClass *class,
@@ -40,15 +38,13 @@ static void g_param_spec_finalize (GParamSpec *pspec);
/* --- functions --- */
void
g_param_types_init (void) /* sync with glib-gtype.c */
g_param_type_init (void) /* sync with gtype.c */
{
static const GTypeFundamentalInfo finfo = {
(G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE |
G_TYPE_FLAG_DERIVABLE |
G_TYPE_FLAG_DEEP_DERIVABLE),
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static const GTypeInfo param_spec_info = {
sizeof (GParamSpecClass),
@@ -57,20 +53,18 @@ g_param_types_init (void) /* sync with glib-gtype.c */
(GBaseFinalizeFunc) g_param_spec_class_base_finalize,
(GClassInitFunc) g_param_spec_class_init,
(GClassFinalizeFunc) NULL,
NULL /* class_data */,
NULL, /* class_data */
sizeof (GParamSpec),
0 /* n_preallocs */,
0, /* n_preallocs */
(GInstanceInitFunc) g_param_spec_init,
NULL, /* value_table */
};
GType type;
type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &finfo, &param_spec_info);
type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &param_spec_info, &finfo);
g_assert (type == G_TYPE_PARAM);
/* derived param specs
*/
g_param_spec_types_init ();
}
static void
@@ -87,16 +81,11 @@ static void
g_param_spec_class_init (GParamSpecClass *class,
gpointer class_data)
{
class->value_type = G_TYPE_NONE;
class->finalize = g_param_spec_finalize;
class->param_init = NULL;
class->param_free_value = NULL;
class->param_validate = NULL;
class->param_values_cmp = NULL;
class->param_copy_value = NULL;
class->collect_type = 0;
class->param_collect_value = NULL;
class->lcopy_type = 0;
class->param_lcopy_value = NULL;
class->value_set_default = NULL;
class->value_validate = NULL;
class->values_cmp = NULL;
}
static void
@@ -209,6 +198,81 @@ g_param_spec_steal_qdata (GParamSpec *pspec,
return g_datalist_id_remove_no_notify (&pspec->qdata, quark);
}
void
g_param_value_set_default (GParamSpec *pspec,
GValue *value)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (G_IS_VALUE (value));
g_return_if_fail (G_IS_PARAM_VALUE (pspec, value));
g_value_reset (value);
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value);
}
gboolean
g_param_value_defaults (GParamSpec *pspec,
GValue *value)
{
GValue dflt_value = { 0, };
gboolean defaults;
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
g_value_init (&dflt_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value);
defaults = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value, &dflt_value) == 0;
g_value_unset (&dflt_value);
return defaults;
}
gboolean
g_param_value_validate (GParamSpec *pspec,
GValue *value)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate)
{
GValue oval = *value;
if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate (pspec, value) ||
memcmp (&oval.data, &value->data, sizeof (oval.data)))
return TRUE;
}
return FALSE;
}
gint
g_param_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
gint cmp;
/* param_values_cmp() effectively does: value1 - value2
* so the return values are:
* -1) value1 < value2
* 0) value1 == value2
* 1) value1 > value2
*/
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
g_return_val_if_fail (G_IS_VALUE (value1), 0);
g_return_val_if_fail (G_IS_VALUE (value2), 0);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value1), 0);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value2), 0);
cmp = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value1, value2);
return CLAMP (cmp, -1, 1);
}
static guint
param_spec_hash (gconstpointer key_spec)
{

View File

@@ -22,7 +22,7 @@
#define __G_PARAM_H__
#include <gobject/gtype.h>
#include <gobject/gvalue.h>
#ifdef __cplusplus
@@ -37,7 +37,8 @@ extern "C" {
#define G_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM, GParamSpec))
#define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM))
#define G_PARAM_SPEC_GET_CLASS(pspec) (G_TYPE_INSTANCE_GET_CLASS ((pspec), G_TYPE_PARAM, GParamSpecClass))
#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM))
#define G_IS_PARAM_VALUE(pspec, value) (g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) // FIXME
#define G_PARAM_SPEC_VALUE_TYPE(pspec) (G_PARAM_SPEC_GET_CLASS (pspec)->value_type)
/* --- flags --- */
@@ -54,39 +55,22 @@ typedef enum
/* --- typedefs & structures --- */
typedef struct _GParamSpecClass GParamSpecClass;
typedef struct _GParamSpec GParamSpec;
typedef struct _GValue GValue;
typedef union _GParamCValue GParamCValue;
typedef void (*GValueExchange) (GValue*, GValue*);
struct _GParamSpecClass
{
GTypeClass g_type_class;
GType value_type;
void (*finalize) (GParamSpec *pspec);
/* GParam methods */
void (*param_init) (GValue *value,
GParamSpec *pspec);
void (*param_free_value) (GValue *value);
gboolean (*param_validate) (GValue *value,
GParamSpec *pspec);
gint (*param_values_cmp) (const GValue *value1,
const GValue *value2,
GParamSpec *pspec);
void (*param_copy_value) (const GValue *src_value,
GValue *dest_value);
/* varargs functionality (optional) */
guint collect_type;
gchar* (*param_collect_value) (GValue *value,
GParamSpec *pspec,
guint nth_value,
GType *collect_type,
GParamCValue *collect_value);
guint lcopy_type;
gchar* (*param_lcopy_value) (const GValue *value,
GParamSpec *pspec,
guint nth_value,
GType *collect_type,
GParamCValue *collect_value);
void (*value_set_default) (GParamSpec *pspec,
GValue *value);
gboolean (*value_validate) (GParamSpec *pspec,
GValue *value);
gint (*values_cmp) (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
};
struct _GParamSpec
{
@@ -118,6 +102,15 @@ void g_param_spec_set_qdata_full (GParamSpec *pspec,
GDestroyNotify destroy);
gpointer g_param_spec_steal_qdata (GParamSpec *pspec,
GQuark quark);
void g_param_value_set_default (GParamSpec *pspec,
GValue *value);
gboolean g_param_value_defaults (GParamSpec *pspec,
GValue *value);
gboolean g_param_value_validate (GParamSpec *pspec,
GValue *value);
gint g_param_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
/* --- private --- */
@@ -140,6 +133,8 @@ GParamSpec* g_param_spec_hash_table_lookup (GHashTable *hash_table,
/* contracts:
*
* +++ OUTDATED +++
*
* class functions may not evaluate param->pspec directly,
* instead, pspec will be passed as argument if required.

File diff suppressed because it is too large Load Diff

View File

@@ -33,61 +33,48 @@ extern "C" {
/* --- type macros --- */
#define G_IS_VALUE_CHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_CHAR))
#define G_IS_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_CHAR))
#define G_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_CHAR, GParamSpecChar))
#define G_IS_VALUE_UCHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UCHAR))
#define G_IS_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UCHAR))
#define G_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UCHAR, GParamSpecUChar))
#define G_IS_VALUE_BOOL(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_BOOL))
#define G_IS_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOL))
#define G_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOL, GParamSpecBool))
#define G_IS_VALUE_INT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_INT))
#define G_IS_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOLEAN))
#define G_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOLEAN, GParamSpecBoolean))
#define G_IS_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_INT))
#define G_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_INT, GParamSpecInt))
#define G_IS_VALUE_UINT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UINT))
#define G_IS_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UINT))
#define G_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UINT, GParamSpecUInt))
#define G_IS_VALUE_LONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_LONG))
#define G_IS_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_LONG))
#define G_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_LONG, GParamSpecLong))
#define G_IS_VALUE_ULONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ULONG))
#define G_IS_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ULONG))
#define G_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ULONG, GParamSpecULong))
#define G_IS_VALUE_ENUM(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ENUM))
#define G_IS_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ENUM))
#define G_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ENUM, GParamSpecEnum))
#define G_IS_VALUE_FLAGS(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLAGS))
#define G_IS_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLAGS))
#define G_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLAGS, GParamSpecFlags))
#define G_IS_VALUE_FLOAT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLOAT))
#define G_IS_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLOAT))
#define G_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLOAT, GParamSpecFloat))
#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_DOUBLE))
#define G_IS_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_DOUBLE))
#define G_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_DOUBLE, GParamSpecDouble))
#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_STRING))
#define G_IS_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_STRING))
#define G_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_STRING, GParamSpecString))
#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_OBJECT))
#define G_IS_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OBJECT))
#define G_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OBJECT, GParamSpecObject))
/* --- typedefs & structures --- */
typedef struct _GParamSpecChar GParamSpecChar;
typedef struct _GParamSpecUChar GParamSpecUChar;
typedef struct _GParamSpecBool GParamSpecBool;
typedef struct _GParamSpecInt GParamSpecInt;
typedef struct _GParamSpecUInt GParamSpecUInt;
typedef struct _GParamSpecLong GParamSpecLong;
typedef struct _GParamSpecULong GParamSpecULong;
typedef struct _GParamSpecEnum GParamSpecEnum;
typedef struct _GParamSpecFlags GParamSpecFlags;
typedef struct _GParamSpecFloat GParamSpecFloat;
typedef struct _GParamSpecDouble GParamSpecDouble;
typedef struct _GParamSpecString GParamSpecString;
typedef struct _GParamSpecObject GParamSpecObject;
typedef struct _GParamSpecChar GParamSpecChar;
typedef struct _GParamSpecUChar GParamSpecUChar;
typedef struct _GParamSpecBoolean GParamSpecBoolean;
typedef struct _GParamSpecInt GParamSpecInt;
typedef struct _GParamSpecUInt GParamSpecUInt;
typedef struct _GParamSpecLong GParamSpecLong;
typedef struct _GParamSpecULong GParamSpecULong;
typedef struct _GParamSpecEnum GParamSpecEnum;
typedef struct _GParamSpecFlags GParamSpecFlags;
typedef struct _GParamSpecFloat GParamSpecFloat;
typedef struct _GParamSpecDouble GParamSpecDouble;
typedef struct _GParamSpecString GParamSpecString;
typedef struct _GParamSpecObject GParamSpecObject;
struct _GParamSpecChar
{
GParamSpec parent_instance;
@@ -104,7 +91,7 @@ struct _GParamSpecUChar
guint8 maximum;
guint8 default_value;
};
struct _GParamSpecBool
struct _GParamSpecBoolean
{
GParamSpec parent_instance;
@@ -193,50 +180,6 @@ struct _GParamSpecObject
};
/* --- GValue prototypes --- */
void g_value_set_char (GValue *value,
gint8 v_char);
gint8 g_value_get_char (GValue *value);
void g_value_set_uchar (GValue *value,
guint8 v_uchar);
guint8 g_value_get_uchar (GValue *value);
void g_value_set_bool (GValue *value,
gboolean v_bool);
gboolean g_value_get_bool (GValue *value);
void g_value_set_int (GValue *value,
gint v_int);
gint g_value_get_int (GValue *value);
void g_value_set_uint (GValue *value,
guint v_uint);
guint g_value_get_uint (GValue *value);
void g_value_set_long (GValue *value,
glong v_long);
glong g_value_get_long (GValue *value);
void g_value_set_ulong (GValue *value,
gulong v_ulong);
gulong g_value_get_ulong (GValue *value);
void g_value_set_enum (GValue *value,
gint v_enum);
gint g_value_get_enum (GValue *value);
void g_value_set_flags (GValue *value,
guint v_flags);
guint g_value_get_flags (GValue *value);
void g_value_set_float (GValue *value,
gfloat v_float);
gfloat g_value_get_float (GValue *value);
void g_value_set_double (GValue *value,
gdouble v_double);
gdouble g_value_get_double (GValue *value);
void g_value_set_string (GValue *value,
const gchar *v_string);
gchar* g_value_get_string (GValue *value);
gchar* g_value_dup_string (GValue *value);
void g_value_set_object (GValue *value,
GObject *v_object);
GObject* g_value_get_object (GValue *value);
GObject* g_value_dup_object (GValue *value);
/* --- GParamSpec prototypes --- */
GParamSpec* g_param_spec_char (const gchar *name,
const gchar *nick,
@@ -252,7 +195,7 @@ GParamSpec* g_param_spec_uchar (const gchar *name,
guint8 maximum,
guint8 default_value,
GParamFlags flags);
GParamSpec* g_param_spec_bool (const gchar *name,
GParamSpec* g_param_spec_boolean (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean default_value,

View File

@@ -18,8 +18,6 @@
*/
#include "gtype.h"
#include "genums.h"
#include "gobject.h"
#include <string.h>
#define FIXME_DISABLE_PREALLOCATIONS
@@ -45,7 +43,7 @@
G_TYPE_FLAG_DEEP_DERIVABLE)
#define g_type_plugin_ref(p) ((p)->vtable->plugin_ref (p))
#define g_type_plugin_unref(p) ((p)->vtable->plugin_unref (p))
#define g_type_plugin_complete_type_info(p,t,i) ((p)->vtable->complete_type_info ((p), (t), (i)))
#define g_type_plugin_complete_type_info(p,t,i,v) ((p)->vtable->complete_type_info ((p), (t), (i), (v)))
#define g_type_plugin_complete_interface_info(p,f,t,i) ((p)->vtable->complete_interface_info ((p), (f), (t), (i)))
typedef struct _TypeNode TypeNode;
@@ -61,10 +59,13 @@ typedef struct _IFaceHolder IFaceHolder;
/* --- prototypes --- */
static inline GTypeFundamentalInfo* type_node_fundamental_info (TypeNode *node);
static void type_data_make (TypeNode *node,
const GTypeInfo *info);
const GTypeInfo *info,
const GTypeValueTable *value_table);
static inline void type_data_ref (TypeNode *node);
static inline void type_data_unref (TypeNode *node);
static void type_data_last_unref (GType type);
static inline void type_data_unref (TypeNode *node,
gboolean uncached);
static void type_data_last_unref (GType type,
gboolean uncached);
/* --- structures --- */
@@ -83,7 +84,7 @@ struct _TypeNode
GData *static_gdata;
union {
IFaceEntry *iface_entries;
IFaceHolder *iholders;
IFaceHolder *iface_conformants;
} private;
GType supers[1]; /* flexible array */
};
@@ -99,21 +100,27 @@ struct _IFaceHolder
GTypePlugin *plugin;
IFaceHolder *next;
};
struct _IFaceEntry
{
GType iface_type;
GTypeInterface *vtable;
};
struct _CommonData
{
guint ref_count;
guint ref_count;
GTypeValueTable *value_table;
};
struct _IFaceData
{
CommonData common;
guint vtable_size;
guint16 vtable_size;
GBaseInitFunc vtable_init_base;
GBaseFinalizeFunc vtable_finalize_base;
};
struct _ClassData
{
CommonData common;
guint class_size;
guint16 class_size;
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
@@ -124,7 +131,7 @@ struct _ClassData
struct _InstanceData
{
CommonData common;
guint class_size;
guint16 class_size;
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
@@ -143,11 +150,15 @@ union _TypeData
ClassData class;
InstanceData instance;
};
struct _IFaceEntry
{
GType iface_type;
GTypeInterface *vtable;
};
typedef struct {
gpointer cache_data;
GTypeClassCacheFunc cache_func;
} ClassCacheFunc;
/* --- variables --- */
static guint n_class_cache_funcs = 0;
static ClassCacheFunc *class_cache_funcs = NULL;
/* --- externs --- */
@@ -193,7 +204,7 @@ type_node_any_new (TypeNode *pnode,
g_type_nodes[ftype] = g_renew (TypeNode*, g_type_nodes[ftype], 1 << g_bit_storage (g_branch_seqnos[ftype] - 1));
if (!pnode)
node_size += sizeof (GTypeFundamentalInfo); /* fundamental type */
node_size += sizeof (GTypeFundamentalInfo); /* fundamental type info */
node_size += SIZEOF_BASE_TYPE_NODE (); /* TypeNode structure */
node_size += sizeof (GType[1 + n_supers + 1]); /* self + anchestors + 0 for ->supers[] */
node = g_malloc0 (node_size);
@@ -213,7 +224,7 @@ type_node_any_new (TypeNode *pnode,
node->n_ifaces = 0;
if (node->is_iface)
node->private.iholders = NULL;
node->private.iface_conformants = NULL;
else
node->private.iface_entries = NULL;
}
@@ -229,7 +240,7 @@ type_node_any_new (TypeNode *pnode,
if (node->is_iface)
{
node->n_ifaces = 0;
node->private.iholders = NULL;
node->private.iface_conformants = NULL;
}
else
{
@@ -315,8 +326,8 @@ type_node_new (TypeNode *pnode,
}
static inline IFaceEntry*
type_lookup_iface_entry (TypeNode *node,
TypeNode *iface)
type_lookup_iface_entry (TypeNode *node,
TypeNode *iface)
{
if (iface->is_iface && node->n_ifaces)
{
@@ -476,10 +487,59 @@ check_derivation (GType parent_type,
}
static gboolean
check_type_info (TypeNode *pnode,
GType ftype,
const gchar *type_name,
const GTypeInfo *info)
check_value_table (const gchar *type_name,
const GTypeValueTable *value_table)
{
if (!value_table)
return FALSE;
else if (value_table->value_init == NULL)
{
if (value_table->value_free || value_table->value_copy ||
value_table->collect_type || value_table->collect_value ||
value_table->lcopy_type || value_table->lcopy_value)
g_warning ("cannot handle uninitializable values of type `%s'",
type_name);
return FALSE;
}
else /* value_table->value_init != NULL */
{
if (!value_table->value_free)
{
/* +++ optional +++
* g_warning ("missing `value_free()' for type `%s'", type_name);
* return FALSE;
*/
}
if (!value_table->value_copy)
{
g_warning ("missing `value_copy()' for type `%s'", type_name);
return FALSE;
}
if ((value_table->collect_type || value_table->collect_value) &&
(!value_table->collect_type || !value_table->collect_value))
{
g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'",
type_name);
return FALSE;
}
if ((value_table->lcopy_type || value_table->lcopy_value) &&
(!value_table->lcopy_type || !value_table->lcopy_value))
{
g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'",
type_name);
return FALSE;
}
}
return TRUE;
}
static gboolean
check_type_info (TypeNode *pnode,
GType ftype,
const gchar *type_name,
const GTypeInfo *info)
{
GTypeFundamentalInfo *finfo = type_node_fundamental_info (LOOKUP_TYPE_NODE (ftype));
gboolean is_interface = G_TYPE_IS_INTERFACE (ftype);
@@ -636,16 +696,37 @@ check_interface_info (TypeNode *iface,
/* --- type info (type node data) --- */
static void
type_data_make (TypeNode *node,
const GTypeInfo *info)
type_data_make (TypeNode *node,
const GTypeInfo *info,
const GTypeValueTable *value_table)
{
TypeData *data = NULL;
TypeData *data;
GTypeValueTable *vtable = NULL;
guint vtable_size = 0;
g_assert (node->data == NULL && info != NULL);
if (!value_table)
{
TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
if (pnode)
vtable = pnode->data->common.value_table;
else
{
static const GTypeValueTable zero_vtable = { NULL, };
value_table = &zero_vtable;
}
}
if (value_table)
vtable_size = sizeof (GTypeValueTable);
if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */
{
data = g_malloc0 (sizeof (InstanceData));
data = g_malloc0 (sizeof (InstanceData) + vtable_size);
if (vtable_size)
vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
data->instance.class_size = info->class_size;
data->instance.class_init_base = info->base_init;
data->instance.class_finalize_base = info->base_finalize;
@@ -663,7 +744,9 @@ type_data_make (TypeNode *node,
}
else if (node->is_classed) /* only classed */
{
data = g_malloc0 (sizeof (ClassData));
data = g_malloc0 (sizeof (ClassData) + vtable_size);
if (vtable_size)
vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
data->class.class_size = info->class_size;
data->class.class_init_base = info->base_init;
data->class.class_finalize_base = info->base_finalize;
@@ -674,16 +757,28 @@ type_data_make (TypeNode *node,
}
else if (node->is_iface)
{
data = g_malloc0 (sizeof (IFaceData));
data = g_malloc0 (sizeof (IFaceData) + vtable_size);
if (vtable_size)
vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData));
data->iface.vtable_size = info->class_size;
data->iface.vtable_init_base = info->base_init;
data->iface.vtable_finalize_base = info->base_finalize;
}
else
data = g_malloc0 (sizeof (CommonData));
{
data = g_malloc0 (sizeof (CommonData) + vtable_size);
if (vtable_size)
vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData));
}
node->data = data;
node->data->common.ref_count = 1;
if (vtable_size)
*vtable = *value_table;
node->data->common.value_table = vtable;
g_assert (node->data->common.value_table != NULL); // FIXME: paranoid
}
static inline void
@@ -692,18 +787,21 @@ type_data_ref (TypeNode *node)
if (!node->data)
{
TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
GTypeInfo tmpinfo;
GTypeInfo tmp_info;
GTypeValueTable tmp_value_table;
g_assert (node->plugin != NULL);
if (pnode)
type_data_ref (pnode);
memset (&tmpinfo, 0, sizeof (tmpinfo));
memset (&tmp_info, 0, sizeof (tmp_info));
memset (&tmp_value_table, 0, sizeof (tmp_value_table));
g_type_plugin_ref (node->plugin);
g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmpinfo);
check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmpinfo);
type_data_make (node, &tmpinfo);
g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
type_data_make (node, &tmp_info,
check_value_table (NODE_NAME (node), &tmp_value_table) ? &tmp_value_table : NULL);
}
else
{
@@ -714,7 +812,8 @@ type_data_ref (TypeNode *node)
}
static inline void
type_data_unref (TypeNode *node)
type_data_unref (TypeNode *node,
gboolean uncached)
{
g_assert (node->data && node->data->common.ref_count);
@@ -729,7 +828,7 @@ type_data_unref (TypeNode *node)
return;
}
type_data_last_unref (NODE_TYPE (node));
type_data_last_unref (NODE_TYPE (node), uncached);
}
}
@@ -769,8 +868,8 @@ type_add_interface (TypeNode *node,
*/
g_assert (node->is_instantiatable && iface->is_iface && ((info && !plugin) || (!info && plugin)));
iholder->next = iface->private.iholders;
iface->private.iholders = iholder;
iholder->next = iface->private.iface_conformants;
iface->private.iface_conformants = iholder;
iholder->instance_type = NODE_TYPE (node);
iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
iholder->plugin = plugin;
@@ -782,7 +881,7 @@ static IFaceHolder*
type_iface_retrive_holder_info (TypeNode *iface,
GType instance_type)
{
IFaceHolder *iholder = iface->private.iholders;
IFaceHolder *iholder = iface->private.iface_conformants;
g_assert (iface->is_iface);
@@ -791,17 +890,17 @@ type_iface_retrive_holder_info (TypeNode *iface,
if (!iholder->info)
{
GInterfaceInfo tmpinfo;
GInterfaceInfo tmp_info;
g_assert (iholder->plugin != NULL);
type_data_ref (iface);
memset (&tmpinfo, 0, sizeof (tmpinfo));
memset (&tmp_info, 0, sizeof (tmp_info));
g_type_plugin_ref (iholder->plugin);
g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmpinfo);
check_interface_info (iface, instance_type, &tmpinfo);
iholder->info = g_memdup (&tmpinfo, sizeof (tmpinfo));
g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
check_interface_info (iface, instance_type, &tmp_info);
iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
}
return iholder;
@@ -811,7 +910,7 @@ static void
type_iface_blow_holder_info (TypeNode *iface,
GType instance_type)
{
IFaceHolder *iholder = iface->private.iholders;
IFaceHolder *iholder = iface->private.iface_conformants;
g_assert (iface->is_iface);
@@ -824,7 +923,7 @@ type_iface_blow_holder_info (TypeNode *iface,
iholder->info = NULL;
g_type_plugin_unref (iholder->plugin);
type_data_unref (iface);
type_data_unref (iface, FALSE);
}
}
@@ -947,7 +1046,7 @@ type_iface_vtable_finalize (TypeNode *iface,
GTypeInterface *vtable)
{
IFaceEntry *entry = type_lookup_iface_entry (node, iface);
IFaceHolder *iholder = iface->private.iholders;
IFaceHolder *iholder = iface->private.iface_conformants;
g_assert (entry && entry->vtable == vtable);
@@ -1081,10 +1180,11 @@ type_data_finalize_class (TypeNode *node,
}
static void
type_data_last_unref (GType type)
type_data_last_unref (GType type,
gboolean uncached)
{
TypeNode *node = LOOKUP_TYPE_NODE (type);
g_return_if_fail (node != NULL && node->plugin != NULL);
if (!node->data || node->data->common.ref_count == 0)
@@ -1093,12 +1193,22 @@ type_data_last_unref (GType type)
type_descriptive_name (type));
return;
}
if (node->is_classed && node->data && node->data->class.class)
{
guint i;
for (i = 0; i < n_class_cache_funcs; i++)
if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class))
break;
}
if (node->data->common.ref_count > 1) /* may have been re-referenced meanwhile */
node->data->common.ref_count -= 1;
else
{
GType ptype = NODE_PARENT_TYPE (node);
TypeData *tdata;
node->data->common.ref_count = 0;
@@ -1108,43 +1218,79 @@ type_data_last_unref (GType type)
node->data->instance.mem_chunk = NULL;
}
if (node->is_classed && node->data->class.class)
tdata = node->data;
if (node->is_classed && tdata->class.class)
{
ClassData *cdata = &node->data->class;
if (node->n_ifaces)
type_data_finalize_class_ifaces (node);
node->data = NULL;
type_data_finalize_class (node, cdata);
g_free (cdata);
type_data_finalize_class (node, &tdata->class);
}
else
{
g_free (node->data);
node->data = NULL;
}
node->data = NULL;
g_free (tdata);
if (ptype)
type_data_unref (LOOKUP_TYPE_NODE (ptype));
type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
g_type_plugin_unref (node->plugin);
}
}
void
g_type_add_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func)
{
guint i;
g_return_if_fail (cache_func != NULL);
i = n_class_cache_funcs++;
class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
class_cache_funcs[i].cache_data = cache_data;
class_cache_funcs[i].cache_func = cache_func;
}
void
g_type_remove_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func)
{
guint i;
g_return_if_fail (cache_func != NULL);
for (i = 0; i < n_class_cache_funcs; i++)
if (class_cache_funcs[i].cache_data == cache_data &&
class_cache_funcs[i].cache_func == cache_func)
{
n_class_cache_funcs--;
g_memmove (class_cache_funcs + i,
class_cache_funcs + i + 1,
sizeof (class_cache_funcs[0]) * (n_class_cache_funcs - i));
class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
return;
}
g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
cache_func, cache_data);
}
/* --- type registration --- */
GType
g_type_register_fundamental (GType type_id,
const gchar *type_name,
const GTypeFundamentalInfo *finfo,
const GTypeInfo *info)
const GTypeInfo *info,
const GTypeFundamentalInfo *finfo)
{
GTypeFundamentalInfo *node_finfo;
TypeNode *node;
g_return_val_if_fail (type_id > 0, 0);
g_return_val_if_fail (type_name != NULL, 0);
g_return_val_if_fail (finfo != NULL, 0);
g_return_val_if_fail (info != NULL, 0);
g_return_val_if_fail (finfo != NULL, 0);
if (!check_type_name (type_name))
return 0;
@@ -1172,12 +1318,11 @@ g_type_register_fundamental (GType type_id,
node = type_node_fundamental_new (type_id, type_name, finfo->type_flags);
node_finfo = type_node_fundamental_info (node);
node_finfo->n_collect_bytes = finfo->n_collect_bytes; // FIXME: check max bytes
node_finfo->param_collector = finfo->param_collector;
if (!check_type_info (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
return NODE_TYPE (node);
type_data_make (node, info);
type_data_make (node, info,
check_value_table (type_name, info->value_table) ? info->value_table : NULL);
return NODE_TYPE (node);
}
@@ -1213,7 +1358,8 @@ g_type_register_static (GType parent_type,
node = type_node_new (pnode, type_name, NULL);
type = NODE_TYPE (node);
type_data_make (node, info);
type_data_make (node, info,
check_value_table (type_name, info->value_table) ? info->value_table : NULL);
return type;
}
@@ -1333,7 +1479,24 @@ g_type_class_unref (gpointer g_class)
node = LOOKUP_TYPE_NODE (class->g_type);
if (node && node->is_classed && node->data &&
node->data->class.class == class && node->data->common.ref_count > 0)
type_data_unref (node);
type_data_unref (node, FALSE);
else
g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
type_descriptive_name (class->g_type));
}
void
g_type_class_unref_uncached (gpointer g_class)
{
TypeNode *node;
GTypeClass *class = g_class;
g_return_if_fail (g_class != NULL);
node = LOOKUP_TYPE_NODE (class->g_type);
if (node && node->is_classed && node->data &&
node->data->class.class == class && node->data->common.ref_count > 0)
type_data_unref (node, TRUE);
else
g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
type_descriptive_name (class->g_type));
@@ -1391,6 +1554,17 @@ g_type_interface_peek (gpointer instance_class,
return NULL;
}
GTypeValueTable*
g_type_value_table_peek (GType type)
{
TypeNode *node = LOOKUP_TYPE_NODE (type);
if (node && node->data && node->data->common.ref_count > 0)
return node->data->common.value_table->value_init ? node->data->common.value_table : NULL;
else
return NULL;
}
gchar*
g_type_name (GType type)
{
@@ -1769,9 +1943,11 @@ g_type_check_class_cast (GTypeClass *type_class,
/* --- foreign prototypes --- */
extern void g_param_types_init (void); /* sync with glib-gparam.c */
extern void g_enum_types_init (void); /* sync with glib-genums.c */
extern void g_object_type_init (void); /* sync with glib-gobject.c */
extern void g_value_types_init (void); /* sync with gvaluetypes.c */
extern void g_enum_types_init (void); /* sync with genums.c */
extern void g_param_type_init (void); /* sync with gparam.c */
extern void g_object_type_init (void); /* sync with gobject.c */
extern void g_param_spec_types_init (void); /* sync with gparamspecs.c */
/* --- initialization --- */
@@ -1808,18 +1984,26 @@ g_type_init (void)
memset (&info, 0, sizeof (info));
node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE);
type = NODE_TYPE (node);
type_data_make (node, &info);
type_data_make (node, &info, NULL); // FIXME
g_assert (type == G_TYPE_INTERFACE);
/* G_TYPE_* value types
*/
g_value_types_init ();
/* G_TYPE_ENUM & G_TYPE_FLAGS
*/
g_enum_types_init ();
/* G_TYPE_PARAM
*/
g_param_types_init ();
g_param_type_init ();
/* G_TYPE_OBJECT
*/
g_object_type_init ();
/* G_TYPE_PARAM_* pspec types
*/
g_param_spec_types_init ();
}

View File

@@ -47,36 +47,42 @@ typedef enum /*< skip >*/
G_TYPE_INTERFACE,
/* GLib type ids */
G_TYPE_CHAR,
G_TYPE_UCHAR,
G_TYPE_BOOLEAN,
G_TYPE_INT,
G_TYPE_UINT,
G_TYPE_LONG,
G_TYPE_ULONG,
G_TYPE_ENUM,
G_TYPE_FLAGS,
G_TYPE_FLOAT,
G_TYPE_DOUBLE,
G_TYPE_STRING,
G_TYPE_PARAM,
G_TYPE_OBJECT,
/* reserved type ids, mail gtk-devel-list@redhat.com for reservations */
G_TYPE_BSE_PROCEDURE,
G_TYPE_GLE_GOBJECT,
/* the following reserved ids should vanish soon */
G_TYPE_GTK_CHAR,
G_TYPE_GTK_UCHAR,
G_TYPE_GTK_BOOL,
G_TYPE_GTK_INT,
G_TYPE_GTK_UINT,
G_TYPE_GTK_LONG,
G_TYPE_GTK_ULONG,
G_TYPE_GTK_FLOAT,
G_TYPE_GTK_DOUBLE,
G_TYPE_GTK_STRING,
G_TYPE_GTK_BOXED,
G_TYPE_GTK_POINTER,
G_TYPE_GTK_SIGNAL,
/* reserved fundamental type ids,
* mail gtk-devel-list@redhat.com for reservations
*/
G_TYPE_BSE_PROCEDURE,
G_TYPE_BSE_TIME,
G_TYPE_BSE_NOTE,
G_TYPE_BSE_DOTS,
G_TYPE_GLE_GOBJECT,
G_TYPE_LAST_RESERVED_FUNDAMENTAL,
/* derived type ids */
/* FIXME: G_TYPE_PARAM_INTERFACE */
G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
G_TYPE_PARAM_BOOL = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
G_TYPE_PARAM_BOOLEAN = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
G_TYPE_PARAM_INT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 4),
G_TYPE_PARAM_UINT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 5),
G_TYPE_PARAM_LONG = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 6),
@@ -86,6 +92,7 @@ typedef enum /*< skip >*/
G_TYPE_PARAM_FLOAT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 10),
G_TYPE_PARAM_DOUBLE = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 11),
G_TYPE_PARAM_STRING = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 12),
/* FIXME: G_TYPE_PARAM_PARAM */
G_TYPE_PARAM_OBJECT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13)
} GTypeFundamentals;
@@ -103,7 +110,8 @@ typedef enum /*< skip >*/
/* Typedefs
*/
typedef guint32 GType;
typedef struct _GParam GParam;
typedef struct _GValue GValue;
typedef union _GTypeCValue GTypeCValue;
typedef struct _GTypePlugin GTypePlugin;
typedef struct _GTypePluginVTable GTypePluginVTable;
typedef struct _GTypeClass GTypeClass;
@@ -112,20 +120,24 @@ typedef struct _GTypeInstance GTypeInstance;
typedef struct _GTypeInfo GTypeInfo;
typedef struct _GTypeFundamentalInfo GTypeFundamentalInfo;
typedef struct _GInterfaceInfo GInterfaceInfo;
typedef struct _GTypeValueTable GTypeValueTable;
/* Basic Type Structures
*/
struct _GTypeClass
{
/*< private >*/
GType g_type;
};
struct _GTypeInstance
{
/*< private >*/
GTypeClass *g_class;
};
struct _GTypeInterface
{
/*< private >*/
GType g_type; /* iface type */
GType g_instance_type;
};
@@ -140,6 +152,7 @@ struct _GTypeInterface
#define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), c_type))
#define G_TYPE_FROM_INSTANCE(instance) (G_TYPE_FROM_CLASS (((GTypeInstance*) (instance))->g_class))
#define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type)
#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type)
/* --- prototypes --- */
@@ -166,7 +179,7 @@ GType* g_type_children (GType type,
guint *n_children);
GType* g_type_interfaces (GType type,
guint *n_interfaces);
/* per-type *static* data */
/* per-type _static_ data */
void g_type_set_qdata (GType type,
GQuark quark,
gpointer data);
@@ -175,30 +188,30 @@ gpointer g_type_get_qdata (GType type,
/* --- type registration --- */
typedef void (*GBaseInitFunc) (gpointer g_class);
typedef void (*GBaseFinalizeFunc) (gpointer g_class);
typedef void (*GClassInitFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GClassFinalizeFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GInstanceInitFunc) (GTypeInstance *instance,
gpointer g_class);
typedef void (*GInterfaceInitFunc) (gpointer g_iface,
gpointer iface_data);
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
gpointer iface_data);
typedef gchar* (*GTypeParamCollector) (GParam *param,
guint n_bytes,
guint8 *bytes);
typedef void (*GTypePluginRef) (GTypePlugin *plugin);
typedef void (*GTypePluginUnRef) (GTypePlugin *plugin);
typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin,
GType g_type,
GTypeInfo *info);
typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin,
GType interface_type,
GType instance_type,
GInterfaceInfo *info);
typedef void (*GBaseInitFunc) (gpointer g_class);
typedef void (*GBaseFinalizeFunc) (gpointer g_class);
typedef void (*GClassInitFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GClassFinalizeFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GInstanceInitFunc) (GTypeInstance *instance,
gpointer g_class);
typedef void (*GInterfaceInitFunc) (gpointer g_iface,
gpointer iface_data);
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
gpointer iface_data);
typedef void (*GTypePluginRef) (GTypePlugin *plugin);
typedef void (*GTypePluginUnRef) (GTypePlugin *plugin);
typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin,
GType g_type,
GTypeInfo *info,
GTypeValueTable *value_table);
typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin,
GType interface_type,
GType instance_type,
GInterfaceInfo *info);
typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data,
GTypeClass *g_class);
struct _GTypePlugin
{
GTypePluginVTable *vtable;
@@ -234,12 +247,13 @@ struct _GTypeInfo
guint16 instance_size;
guint16 n_preallocs;
GInstanceInitFunc instance_init;
/* value handling */
const GTypeValueTable *value_table;
};
struct _GTypeFundamentalInfo
{
GTypeFlags type_flags;
guint n_collect_bytes;
GTypeParamCollector param_collector;
};
struct _GInterfaceInfo
{
@@ -247,6 +261,24 @@ struct _GInterfaceInfo
GInterfaceFinalizeFunc interface_finalize;
gpointer interface_data;
};
struct _GTypeValueTable
{
void (*value_init) (GValue *value);
void (*value_free) (GValue *value);
void (*value_copy) (const GValue *src_value,
GValue *dest_value);
/* varargs functionality (optional) */
guint collect_type;
gchar* (*collect_value) (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
guint lcopy_type;
gchar* (*lcopy_value) (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
};
GType g_type_register_static (GType parent_type,
const gchar *type_name,
const GTypeInfo *info);
@@ -255,8 +287,8 @@ GType g_type_register_dynamic (GType parent_type,
GTypePlugin *plugin);
GType g_type_register_fundamental (GType type_id,
const gchar *type_name,
const GTypeFundamentalInfo *finfo,
const GTypeInfo *info);
const GTypeInfo *info,
const GTypeFundamentalInfo *finfo);
void g_type_add_interface_static (GType instance_type,
GType interface_type,
GInterfaceInfo *info);
@@ -266,20 +298,27 @@ void g_type_add_interface_dynamic (GType instance_type,
/* --- implementation details --- */
gboolean g_type_class_is_a (GTypeClass *g_class,
GType is_a_type);
GTypeClass* g_type_check_class_cast (GTypeClass *g_class,
GType is_a_type);
GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance,
GType iface_type);
gboolean g_type_instance_conforms_to (GTypeInstance *instance,
GType iface_type);
gboolean g_type_check_flags (GType type,
GTypeFlags flags);
gboolean g_type_is_dynamic (GType type,
GTypeFlags flags);
GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance);
gboolean g_type_class_is_a (GTypeClass *g_class,
GType is_a_type);
GTypeClass* g_type_check_class_cast (GTypeClass *g_class,
GType is_a_type);
GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance,
GType iface_type);
gboolean g_type_instance_conforms_to (GTypeInstance *instance,
GType iface_type);
gboolean g_type_check_flags (GType type,
GTypeFlags flags);
gboolean g_type_is_dynamic (GType type,
GTypeFlags flags);
GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance);
GTypeValueTable* g_type_value_table_peek (GType type);
void g_type_add_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func);
void g_type_remove_class_cache_func (gpointer cache_data,
GTypeClassCacheFunc cache_func);
void g_type_class_unref_uncached (gpointer g_class);
#ifndef G_DISABLE_CAST_CHECKS
# define _G_TYPE_CIC(ip, gt, ct) \

View File

@@ -19,10 +19,6 @@
#include "gvalue.h"
/* --- defines --- */
#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass))
/* --- typedefs & structures --- */
typedef struct
{
@@ -42,179 +38,73 @@ void
g_value_init (GValue *value,
GType g_type)
{
GParamSpecClass *pclass;
g_return_if_fail (value != NULL);
g_return_if_fail (G_VALUE_TYPE (value) == 0);
g_type = g_type_next_base (g_type, G_TYPE_PARAM);
g_return_if_fail (G_TYPE_IS_VALUE (g_type));
memset (value, 0, sizeof (*value));
value->g_type = g_type;
pclass = g_type_class_ref (G_VALUE_TYPE (value));
pclass->param_init (value, NULL);
g_type_class_unref (pclass);
}
void
g_value_init_default (GValue *value,
GParamSpec *pspec)
{
g_return_if_fail (value != NULL);
g_return_if_fail (G_VALUE_TYPE (value) == 0);
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
memset (value, 0, sizeof (*value));
value->g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (value, pspec);
}
gboolean
g_value_validate (GValue *value,
GParamSpec *pspec)
{
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE);
if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate)
{
GValue oval = *value;
if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate (value, pspec) ||
memcmp (&oval.data, &value->data, sizeof (oval.data)))
return TRUE;
}
return FALSE;
}
gboolean
g_value_defaults (const GValue *value,
GParamSpec *pspec)
{
GValue dflt_value = { 0, };
gboolean defaults;
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE);
GTypeValueTable *value_table = g_type_value_table_peek (g_type);
dflt_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&dflt_value, pspec);
defaults = g_values_cmp (value, &dflt_value, pspec) == 0;
g_value_unset (&dflt_value);
return defaults;
}
void
g_value_set_default (GValue *value,
GParamSpec *pspec)
{
GValue tmp_value = { 0, };
g_return_if_fail (G_IS_VALUE (value));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)));
/* retrive default value */
tmp_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&tmp_value, pspec);
/* set default value */
g_values_exchange (&tmp_value, value);
g_value_unset (&tmp_value);
}
gint
g_values_cmp (const GValue *value1,
const GValue *value2,
GParamSpec *pspec)
{
GParamSpecClass *pclass;
gint cmp;
/* param_values_cmp() effectively does: value1 - value2
* so the return values are:
* -1) value1 < value2
* 0) value1 == value2
* 1) value1 > value2
*/
g_return_val_if_fail (G_IS_VALUE (value1), 0);
g_return_val_if_fail (G_IS_VALUE (value2), 0);
g_return_val_if_fail (G_VALUE_TYPE (value1) == G_VALUE_TYPE (value2), 0);
if (pspec)
g_return_if_fail (value != NULL);
g_return_if_fail (G_VALUE_TYPE (value) == 0);
if (value_table)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value1)), FALSE);
memset (value, 0, sizeof (*value));
value->g_type = g_type;
value_table->value_init (value);
}
pclass = g_type_class_ref (G_VALUE_TYPE (value1));
cmp = pclass->param_values_cmp (value1, value2, pspec);
g_type_class_unref (pclass);
return CLAMP (cmp, -1, 1);
else
g_warning (G_STRLOC ": cannot initialize value of type `%s' which has no GTypeValueTable",
g_type_name (g_type));
}
void
g_value_copy (const GValue *src_value,
GValue *dest_value)
{
GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (dest_value));
g_return_if_fail (G_IS_VALUE (src_value));
g_return_if_fail (G_IS_VALUE (dest_value));
g_return_if_fail (G_VALUE_TYPE (src_value) == G_VALUE_TYPE (dest_value));
g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)));
if (!value_table)
g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (dest_value)) != NULL);
if (src_value != dest_value)
{
GParamSpecClass *pclass = g_type_class_ref (G_VALUE_TYPE (src_value));
/* make sure dest_value's value is free()d and zero initialized */
g_value_reset (dest_value);
if (pclass->param_copy_value)
pclass->param_copy_value (src_value, dest_value);
else
memcpy (&dest_value->data, &src_value->data, sizeof (src_value->data));
g_type_class_unref (pclass);
value_table->value_copy (src_value, dest_value);
}
}
void
g_value_unset (GValue *value)
{
GParamSpecClass *pclass;
GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
g_return_if_fail (G_IS_VALUE (value));
pclass = g_type_class_ref (G_VALUE_TYPE (value));
if (pclass->param_free_value)
pclass->param_free_value (value);
if (!value_table)
g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL);
if (value_table->value_free)
value_table->value_free (value);
memset (value, 0, sizeof (*value));
g_type_class_unref (pclass);
}
void
g_value_reset (GValue *value)
{
GParamSpecClass *pclass;
GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
GType g_type;
g_return_if_fail (G_IS_VALUE (value));
g_type = G_VALUE_TYPE (value);
pclass = g_type_class_ref (g_type);
if (pclass->param_free_value)
pclass->param_free_value (value);
memset (value, 0, sizeof (*value));
value->g_type = g_type;
pclass->param_init (value, NULL);
g_type_class_unref (pclass);
g_return_if_fail (G_IS_VALUE (value));
g_type = G_VALUE_TYPE (value);
if (value_table->value_free)
value_table->value_free (value);
memset (value, 0, sizeof (*value));
value->g_type = g_type;
value_table->value_init (value);
}
static gint
@@ -223,7 +113,7 @@ exchange_entries_equal (gconstpointer v1,
{
const ExchangeEntry *entry1 = v1;
const ExchangeEntry *entry2 = v2;
return (entry1->value_type1 == entry2->value_type1 &&
entry1->value_type2 == entry2->value_type2);
}
@@ -232,7 +122,7 @@ static guint
exchange_entry_hash (gconstpointer key)
{
const ExchangeEntry *entry = key;
return entry->value_type1 ^ entry->value_type2;
}
@@ -241,7 +131,7 @@ value_exchange_memcpy (GValue *value1,
GValue *value2)
{
GValue tmp_value;
memcpy (&tmp_value.data, &value1->data, sizeof (value1->data));
memcpy (&value1->data, &value2->data, sizeof (value1->data));
memcpy (&value2->data, &tmp_value.data, sizeof (value2->data));
@@ -256,20 +146,36 @@ exchange_func_lookup (GType value_type1,
return value_exchange_memcpy;
else
{
ExchangeEntry entry, *ret;
GType type1 = value_type1;
entry.value_type1 = MIN (value_type1, value_type2);
entry.value_type2 = MAX (value_type1, value_type2);
ret = g_hash_table_lookup (param_exchange_ht, &entry);
if (ret)
do
{
if (need_swap)
*need_swap = ret->first_type == value_type1;
return ret->func;
GType type2 = value_type2;
do
{
ExchangeEntry entry, *ret;
entry.value_type1 = MIN (type1, type2);
entry.value_type2 = MAX (type1, type2);
ret = g_hash_table_lookup (param_exchange_ht, &entry);
if (ret)
{
if (need_swap)
*need_swap = ret->first_type == type2;
return ret->func;
}
type2 = g_type_parent (type2);
}
while (type2);
type1 = g_type_parent (type1);
}
while (type1);
}
return NULL;
}
@@ -278,30 +184,29 @@ g_value_register_exchange_func (GType value_type1,
GType value_type2,
GValueExchange func)
{
GType type1, type2;
ExchangeEntry entry;
g_return_if_fail (G_TYPE_IS_VALUE (value_type1));
g_return_if_fail (G_TYPE_IS_VALUE (value_type2));
g_return_if_fail (func != NULL);
type1 = g_type_next_base (value_type1, G_TYPE_PARAM);
type2 = g_type_next_base (value_type2, G_TYPE_PARAM);
if (param_exchange_ht && exchange_func_lookup (type1, type2, NULL))
entry.value_type1 = MIN (value_type1, value_type2);
entry.value_type2 = MAX (value_type1, value_type2);
if (param_exchange_ht && g_hash_table_lookup (param_exchange_ht, &entry))
g_warning (G_STRLOC ": cannot re-register param value exchange function "
"for `%s' and `%s'",
g_type_name (type1),
g_type_name (type2));
g_type_name (value_type1),
g_type_name (value_type2));
else
{
ExchangeEntry *entry = g_new (ExchangeEntry, 1);
if (!param_exchange_ht)
param_exchange_ht = g_hash_table_new (exchange_entry_hash, exchange_entries_equal);
entry->value_type1 = MIN (type1, type2);
entry->value_type2 = MAX (type1, type2);
entry->value_type1 = MIN (value_type1, value_type2);
entry->value_type2 = MAX (value_type1, value_type2);
entry->func = func;
entry->first_type = type1;
entry->first_type = value_type1;
g_hash_table_insert (param_exchange_ht, entry, entry);
}
}
@@ -310,15 +215,10 @@ gboolean
g_value_types_exchangable (GType value_type1,
GType value_type2)
{
GType type1, type2;
g_return_val_if_fail (G_TYPE_IS_VALUE (value_type1), FALSE);
g_return_val_if_fail (G_TYPE_IS_VALUE (value_type2), FALSE);
type1 = g_type_next_base (value_type1, G_TYPE_PARAM);
type2 = g_type_next_base (value_type2, G_TYPE_PARAM);
return exchange_func_lookup (type1, type2, NULL) != NULL;
return exchange_func_lookup (value_type1, value_type2, NULL) != NULL;
}
gboolean
@@ -327,14 +227,12 @@ g_values_exchange (GValue *value1,
{
g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
if (value1 != value2)
{
GType type1 = g_type_next_base (G_VALUE_TYPE (value1), G_TYPE_PARAM);
GType type2 = g_type_next_base (G_VALUE_TYPE (value2), G_TYPE_PARAM);
gboolean need_swap;
GValueExchange value_exchange = exchange_func_lookup (type1,
type2,
GValueExchange value_exchange = exchange_func_lookup (G_VALUE_TYPE (value1),
G_VALUE_TYPE (value2),
&need_swap);
if (value_exchange)
{
@@ -343,10 +241,10 @@ g_values_exchange (GValue *value1,
else
value_exchange (value1, value2);
}
return value_exchange != NULL;
}
return TRUE;
}
@@ -355,20 +253,20 @@ g_value_convert (const GValue *src_value,
GValue *dest_value)
{
gboolean success = TRUE;
g_return_val_if_fail (G_IS_VALUE (src_value), FALSE);
g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE);
if (src_value != dest_value)
{
GValue tmp_value = { 0, };
g_value_init (&tmp_value, G_VALUE_TYPE (src_value));
g_value_copy (src_value, &tmp_value);
success = g_values_exchange (&tmp_value, dest_value);
g_value_unset (&tmp_value);
}
return success;
}

View File

@@ -22,7 +22,7 @@
#define __G_VALUE_H__
#include <gobject/gparam.h>
#include <gobject/gtype.h>
#ifdef __cplusplus
extern "C" {
@@ -30,18 +30,21 @@ extern "C" {
/* --- type macros --- */
#define G_TYPE_IS_VALUE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM)
#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM))
#define G_TYPE_IS_VALUE(type) (g_type_value_table_peek (type) != NULL)
#define G_IS_VALUE(value) (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))) // FIXME
#define G_VALUE_TYPE(value) (G_TYPE_FROM_CLASS (value))
#define G_VALUE_TYPE_NAME(value) (g_type_name (G_VALUE_TYPE (value)))
/* --- typedefs & structures --- */
/* typedef struct _GValue GValue; */
typedef void (*GValueExchange) (GValue *value1,
GValue *value2);
struct _GValue
{
GType g_type; /* param value type */
/*< private >*/
GType g_type;
/* public for GTypeValueTable methods */
union {
gint v_int;
guint v_uint;
@@ -57,28 +60,17 @@ struct _GValue
/* --- prototypes --- */
void g_value_init (GValue *value,
GType g_type);
void g_value_init_default (GValue *value,
GParamSpec *pspec);
gboolean g_value_validate (GValue *value,
GParamSpec *pspec);
gboolean g_value_defaults (const GValue *value,
GParamSpec *pspec);
void g_value_set_default (GValue *value,
GParamSpec *pspec);
gint g_values_cmp (const GValue *value1,
const GValue *value2,
GParamSpec *pspec);
void g_value_copy (const GValue *src_value,
GValue *dest_value);
gboolean g_value_convert (const GValue *src_value,
GValue *dest_value);
gboolean g_values_exchange (GValue *value1,
GValue *value2);
void g_value_reset (GValue *value);
void g_value_unset (GValue *value);
/* --- implementation bits --- */
/* --- implementation details --- */
gboolean g_values_exchange (GValue *value1,
GValue *value2);
gboolean g_value_types_exchangable (GType value_type1,
GType value_type2);
void g_value_register_exchange_func (GType value_type1,

View File

@@ -41,7 +41,7 @@ enum /*< skip >*/
G_VALUE_COLLECT_POINTER
};
union _GParamCValue
union _GTypeCValue
{
gint v_int;
glong v_long;
@@ -50,33 +50,28 @@ union _GParamCValue
};
/* G_PARAM_COLLECT_VALUE() collects a parameter's variable arguments
/* G_VALUE_COLLECT() collects a variable argument value
* from a va_list. we have to implement the varargs collection as a
* macro, because on some systems va_list variables cannot be passed
* by reference.
* param_value is supposed to be initialized according to the param
* value is supposed to be initialized according to the value
* type to be collected.
* the param_spec argument is optional, but probably needed by most
* param class' param_collect_value() implementations.
* var_args is the va_list variable and may be evaluated multiple times.
* __error is a gchar** variable that will be modified to hold a g_new()
* allocated error messages if something fails.
*/
#define G_PARAM_COLLECT_VALUE(param_value, param_spec, var_args, __error) \
#define G_VALUE_COLLECT(value, var_args, __error) \
G_STMT_START { \
GValue *_value = (param_value); \
GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \
GParamSpec *_pspec = (param_spec); \
GValue *_value = (value); \
GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \
gchar *_error_msg = NULL; \
guint _collect_type = _pclass->collect_type; \
guint _collect_type = _vtable->collect_type; \
guint _nth_value = 0; \
\
if (_pspec) \
g_param_spec_ref (_pspec); \
g_value_reset (_value); \
while (_collect_type && !_error_msg) \
{ \
GParamCValue _cvalue; \
GTypeCValue _cvalue; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_collect_type) \
@@ -97,39 +92,32 @@ G_STMT_START { \
_error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \
G_STRLOC, \
_collect_type, \
"G_PARAM_COLLECT_VALUE()"); \
"G_VALUE_COLLECT()"); \
continue; \
} \
_error_msg = _pclass->param_collect_value (_value, \
_pspec, \
_nth_value++, \
&_collect_type, \
&_cvalue); \
_error_msg = _vtable->collect_value (_value, \
_nth_value++, \
&_collect_type, \
&_cvalue); \
} \
*(__error) = _error_msg; \
if (_pspec) \
g_param_spec_unref (_pspec); \
g_type_class_unref (_pclass); \
} G_STMT_END
/* G_PARAM_LCOPY_VALUE() collects a parameter's variable argument
* locations from a va_list. usage is analogous to G_PARAM_COLLECT_VALUE().
/* G_VALUE_LCOPY() collects a value's variable argument
* locations from a va_list. usage is analogous to G_VALUE_COLLECT().
*/
#define G_PARAM_LCOPY_VALUE(param_value, param_spec, var_args, __error) \
#define G_VALUE_LCOPY(value, var_args, __error) \
G_STMT_START { \
GValue *_value = (param_value); \
GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \
GParamSpec *_pspec = (param_spec); \
GValue *_value = (value); \
GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \
gchar *_error_msg = NULL; \
guint _lcopy_type = _pclass->lcopy_type; \
guint _lcopy_type = _vtable->lcopy_type; \
guint _nth_value = 0; \
\
if (_pspec) \
g_param_spec_ref (_pspec); \
while (_lcopy_type && !_error_msg) \
{ \
GParamCValue _cvalue; \
GTypeCValue _cvalue; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_lcopy_type) \
@@ -150,19 +138,15 @@ G_STMT_START { \
_error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \
G_STRLOC, \
_lcopy_type, \
"G_PARAM_LCOPY_VALUE()"); \
"G_VALUE_LCOPY()"); \
continue; \
} \
_error_msg = _pclass->param_lcopy_value (_value, \
_pspec, \
_nth_value++, \
&_lcopy_type, \
&_cvalue); \
_error_msg = _vtable->lcopy_value (_value, \
_nth_value++, \
&_lcopy_type, \
&_cvalue); \
} \
*(__error) = _error_msg; \
if (_pspec) \
g_param_spec_unref (_pspec); \
g_type_class_unref (_pclass); \
} G_STMT_END

588
gobject/gvaluetypes.c Normal file
View File

@@ -0,0 +1,588 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gvaluetypes.h"
#include "gvaluecollector.h"
#include <string.h>
/* --- value functions --- */
static void
value_long0_init (GValue *value)
{
value->data[0].v_long = 0;
}
static void
value_long0_copy (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_long = src_value->data[0].v_long;
}
static gchar*
value_char_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gint8 *int8_p = collect_value->v_pointer;
if (!int8_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int8_p = value->data[0].v_int;
*collect_type = 0;
return NULL;
}
static gchar*
value_boolean_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gboolean *bool_p = collect_value->v_pointer;
if (!bool_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*bool_p = value->data[0].v_int;
*collect_type = 0;
return NULL;
}
static gchar*
value_int_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_int = collect_value->v_int;
*collect_type = 0;
return NULL;
}
static gchar*
value_int_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gint *int_p = collect_value->v_pointer;
if (!int_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int_p = value->data[0].v_int;
*collect_type = 0;
return NULL;
}
static gchar*
value_long_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_long = collect_value->v_long;
*collect_type = 0;
return NULL;
}
static gchar*
value_long_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
glong *long_p = collect_value->v_pointer;
if (!long_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*long_p = value->data[0].v_long;
*collect_type = 0;
return NULL;
}
static void
value_float_init (GValue *value)
{
value->data[0].v_float = 0.0;
}
static void
value_float_copy (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_float = src_value->data[0].v_float;
}
static gchar*
value_float_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_float = collect_value->v_double;
*collect_type = 0;
return NULL;
}
static gchar*
value_float_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gfloat *float_p = collect_value->v_pointer;
if (!float_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*float_p = value->data[0].v_float;
*collect_type = 0;
return NULL;
}
static void
value_double_init (GValue *value)
{
value->data[0].v_double = 0.0;
}
static void
value_double_copy (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_double = src_value->data[0].v_double;
}
static gchar*
value_double_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_double = collect_value->v_double;
*collect_type = 0;
return NULL;
}
static gchar*
value_double_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gdouble *double_p = collect_value->v_pointer;
if (!double_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*double_p = value->data[0].v_double;
*collect_type = 0;
return NULL;
}
static void
value_string_init (GValue *value)
{
value->data[0].v_pointer = NULL;
}
static void
value_string_free_value (GValue *value)
{
g_free (value->data[0].v_pointer);
}
static void
value_string_copy_value (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
}
static gchar*
value_string_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
value->data[0].v_pointer = g_strdup (collect_value->v_pointer);
*collect_type = 0;
return NULL;
}
static gchar*
value_string_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gchar **string_p = collect_value->v_pointer;
if (!string_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*string_p = g_strdup (value->data[0].v_pointer);
*collect_type = 0;
return NULL;
}
/* --- type initialization --- */
void
g_value_types_init (void) /* sync with gtype.c */
{
GTypeInfo info = {
0, /* class_size */
NULL, /* base_init */
NULL, /* base_destroy */
NULL, /* class_init */
NULL, /* class_destroy */
NULL, /* class_data */
0, /* instance_size */
0, /* n_preallocs */
NULL, /* instance_init */
NULL, /* value_table */
};
const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
GType type;
/* G_TYPE_CHAR / G_TYPE_UCHAR
*/
{
static const GTypeValueTable value_table = {
value_long0_init, /* value_init */
NULL, /* value_free */
value_long0_copy, /* value_copy */
G_VALUE_COLLECT_INT, /* collect_type */
value_int_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_char_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo);
g_assert (type == G_TYPE_CHAR);
type = g_type_register_fundamental (G_TYPE_UCHAR, "guchar", &info, &finfo);
g_assert (type == G_TYPE_UCHAR);
}
/* G_TYPE_BOOLEAN
*/
{
static const GTypeValueTable value_table = {
value_long0_init, /* value_init */
NULL, /* value_free */
value_long0_copy, /* value_copy */
G_VALUE_COLLECT_INT, /* collect_type */
value_int_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_boolean_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_BOOLEAN, "gboolean", &info, &finfo);
g_assert (type == G_TYPE_BOOLEAN);
}
/* G_TYPE_INT / G_TYPE_UINT
*/
{
static const GTypeValueTable value_table = {
value_long0_init, /* value_init */
NULL, /* value_free */
value_long0_copy, /* value_copy */
G_VALUE_COLLECT_INT, /* collect_type */
value_int_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_int_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_INT, "gint", &info, &finfo);
g_assert (type == G_TYPE_INT);
type = g_type_register_fundamental (G_TYPE_UINT, "guint", &info, &finfo);
g_assert (type == G_TYPE_UINT);
}
/* G_TYPE_LONG / G_TYPE_ULONG
*/
{
static const GTypeValueTable value_table = {
value_long0_init, /* value_init */
NULL, /* value_free */
value_long0_copy, /* value_copy */
G_VALUE_COLLECT_LONG, /* collect_type */
value_long_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_long_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_LONG, "glong", &info, &finfo);
g_assert (type == G_TYPE_LONG);
type = g_type_register_fundamental (G_TYPE_ULONG, "gulong", &info, &finfo);
g_assert (type == G_TYPE_ULONG);
}
/* G_TYPE_FLOAT
*/
{
static const GTypeValueTable value_table = {
value_float_init, /* value_init */
NULL, /* value_free */
value_float_copy, /* value_copy */
G_VALUE_COLLECT_DOUBLE, /* collect_type */
value_float_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_float_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_FLOAT, "gfloat", &info, &finfo);
g_assert (type == G_TYPE_FLOAT);
}
/* G_TYPE_DOUBLE
*/
{
static const GTypeValueTable value_table = {
value_double_init, /* value_init */
NULL, /* value_free */
value_double_copy, /* value_copy */
G_VALUE_COLLECT_DOUBLE, /* collect_type */
value_double_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_double_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_DOUBLE, "gdouble", &info, &finfo);
g_assert (type == G_TYPE_DOUBLE);
}
/* G_TYPE_STRING
*/
{
static const GTypeValueTable value_table = {
value_string_init, /* value_init */
value_string_free_value, /* value_free */
value_string_copy_value, /* value_copy */
G_VALUE_COLLECT_POINTER, /* collect_type */
value_string_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_string_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_STRING, "gstring", &info, &finfo);
g_assert (type == G_TYPE_STRING);
}
}
/* --- GValue functions --- */
void
g_value_set_char (GValue *value,
gint8 v_char)
{
g_return_if_fail (G_IS_VALUE_CHAR (value));
value->data[0].v_int = v_char;
}
gint8
g_value_get_char (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0);
return value->data[0].v_int;
}
void
g_value_set_uchar (GValue *value,
guint8 v_uchar)
{
g_return_if_fail (G_IS_VALUE_UCHAR (value));
value->data[0].v_uint = v_uchar;
}
guint8
g_value_get_uchar (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0);
return value->data[0].v_uint;
}
void
g_value_set_boolean (GValue *value,
gboolean v_boolean)
{
g_return_if_fail (G_IS_VALUE_BOOLEAN (value));
value->data[0].v_int = v_boolean;
}
gboolean
g_value_get_boolean (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_BOOLEAN (value), 0);
return value->data[0].v_int;
}
void
g_value_set_int (GValue *value,
gint v_int)
{
g_return_if_fail (G_IS_VALUE_INT (value));
value->data[0].v_int = v_int;
}
gint
g_value_get_int (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_INT (value), 0);
return value->data[0].v_int;
}
void
g_value_set_uint (GValue *value,
guint v_uint)
{
g_return_if_fail (G_IS_VALUE_UINT (value));
value->data[0].v_uint = v_uint;
}
guint
g_value_get_uint (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_UINT (value), 0);
return value->data[0].v_uint;
}
void
g_value_set_long (GValue *value,
glong v_long)
{
g_return_if_fail (G_IS_VALUE_LONG (value));
value->data[0].v_long = v_long;
}
glong
g_value_get_long (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_LONG (value), 0);
return value->data[0].v_long;
}
void
g_value_set_ulong (GValue *value,
gulong v_ulong)
{
g_return_if_fail (G_IS_VALUE_ULONG (value));
value->data[0].v_ulong = v_ulong;
}
gulong
g_value_get_ulong (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0);
return value->data[0].v_ulong;
}
void
g_value_set_float (GValue *value,
gfloat v_float)
{
g_return_if_fail (G_IS_VALUE_FLOAT (value));
value->data[0].v_float = v_float;
}
gfloat
g_value_get_float (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0);
return value->data[0].v_float;
}
void
g_value_set_double (GValue *value,
gdouble v_double)
{
g_return_if_fail (G_IS_VALUE_DOUBLE (value));
value->data[0].v_double = v_double;
}
gdouble
g_value_get_double (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0);
return value->data[0].v_double;
}
void
g_value_set_string (GValue *value,
const gchar *v_string)
{
g_return_if_fail (G_IS_VALUE_STRING (value));
g_free (value->data[0].v_pointer);
value->data[0].v_pointer = g_strdup (v_string);
}
gchar*
g_value_get_string (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
return value->data[0].v_pointer;
}
gchar*
g_value_dup_string (GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
return g_strdup (value->data[0].v_pointer);
}

86
gobject/gvaluetypes.h Normal file
View File

@@ -0,0 +1,86 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* gvaluetypes.h: GLib default values
*/
#ifndef __G_VALUETYPES_H__
#define __G_VALUETYPES_H__
#include <gobject/gvalue.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_IS_VALUE_CHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_CHAR))
#define G_IS_VALUE_UCHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UCHAR))
#define G_IS_VALUE_BOOLEAN(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_BOOLEAN))
#define G_IS_VALUE_INT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_INT))
#define G_IS_VALUE_UINT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UINT))
#define G_IS_VALUE_LONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_LONG))
#define G_IS_VALUE_ULONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ULONG))
#define G_IS_VALUE_FLOAT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLOAT))
#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_DOUBLE))
#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_STRING))
/* --- prototypes --- */
void g_value_set_char (GValue *value,
gint8 v_char);
gint8 g_value_get_char (GValue *value);
void g_value_set_uchar (GValue *value,
guint8 v_uchar);
guint8 g_value_get_uchar (GValue *value);
void g_value_set_boolean (GValue *value,
gboolean v_boolean);
gboolean g_value_get_boolean (GValue *value);
void g_value_set_int (GValue *value,
gint v_int);
gint g_value_get_int (GValue *value);
void g_value_set_uint (GValue *value,
guint v_uint);
guint g_value_get_uint (GValue *value);
void g_value_set_long (GValue *value,
glong v_long);
glong g_value_get_long (GValue *value);
void g_value_set_ulong (GValue *value,
gulong v_ulong);
gulong g_value_get_ulong (GValue *value);
void g_value_set_float (GValue *value,
gfloat v_float);
gfloat g_value_get_float (GValue *value);
void g_value_set_double (GValue *value,
gdouble v_double);
gdouble g_value_get_double (GValue *value);
void g_value_set_string (GValue *value,
const gchar *v_string);
gchar* g_value_get_string (GValue *value);
gchar* g_value_dup_string (GValue *value);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_VALUETYPES_H__ */