Home | History | Annotate | Download | only in gobject
      1 /* GObject - GLib Type, Object, Parameter and Signal Library
      2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Lesser General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
     12  * Lesser General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General
     15  * Public License along with this library; if not, write to the
     16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
     17  * Boston, MA 02111-1307, USA.
     18  */
     19 
     20 /*
     21  * MT safe
     22  */
     23 
     24 #include "config.h"
     25 
     26 #include <string.h>
     27 
     28 #include "genums.h"
     29 #include "gvalue.h"
     30 #include "gvaluecollector.h"
     31 #include "gobjectalias.h"
     32 
     33 
     34 /**
     35  * SECTION:enumerations_flags
     36  * @short_description: Enumeration and flags types
     37  * @see_also:#GParamSpecEnum, #GParamSpecFlags, g_param_spec_enum(),
     38  * g_param_spec_flags(),
     39  *
     40  * <link linkend="glib-mkenums">glib-mkenums</link>
     41  * @title: Enumeration and Flag Types
     42  *
     43  * The GLib type system provides fundamental types for enumeration and
     44  * flags types. (Flags types are like enumerations, but allow their
     45  * values to be combined by bitwise or). A registered enumeration or
     46  * flags type associates a name and a nickname with each allowed
     47  * value, and the methods g_enum_get_value_by_name(),
     48  * g_enum_get_value_by_nick(), g_flags_get_value_by_name() and
     49  * g_flags_get_value_by_nick() can look up values by their name or
     50  * nickname.  When an enumeration or flags type is registered with the
     51  * GLib type system, it can be used as value type for object
     52  * properties, using g_param_spec_enum() or g_param_spec_flags().
     53  *
     54  * GObject ships with a utility called <link
     55  * linkend="glib-mkenums">glib-mkenums</link> that can construct
     56  * suitable type registration functions from C enumeration
     57  * definitions.
     58  */
     59 
     60 
     61 /* --- prototypes --- */
     62 static void	g_enum_class_init		(GEnumClass	*class,
     63 						 gpointer	 class_data);
     64 static void	g_flags_class_init		(GFlagsClass	*class,
     65 						 gpointer	 class_data);
     66 static void	value_flags_enum_init		(GValue		*value);
     67 static void	value_flags_enum_copy_value	(const GValue	*src_value,
     68 						 GValue		*dest_value);
     69 static gchar*	value_flags_enum_collect_value  (GValue		*value,
     70 						 guint           n_collect_values,
     71 						 GTypeCValue    *collect_values,
     72 						 guint           collect_flags);
     73 static gchar*	value_flags_enum_lcopy_value	(const GValue	*value,
     74 						 guint           n_collect_values,
     75 						 GTypeCValue    *collect_values,
     76 						 guint           collect_flags);
     77 
     78 /* --- functions --- */
     79 void
     80 g_enum_types_init (void)
     81 {
     82   static gboolean initialized = FALSE;
     83   static const GTypeValueTable flags_enum_value_table = {
     84     value_flags_enum_init,	    /* value_init */
     85     NULL,			    /* value_free */
     86     value_flags_enum_copy_value,    /* value_copy */
     87     NULL,			    /* value_peek_pointer */
     88     "i",			    /* collect_format */
     89     value_flags_enum_collect_value, /* collect_value */
     90     "p",			    /* lcopy_format */
     91     value_flags_enum_lcopy_value,   /* lcopy_value */
     92   };
     93   static GTypeInfo info = {
     94     0,                          /* class_size */
     95     NULL,                       /* base_init */
     96     NULL,                       /* base_destroy */
     97     NULL,                       /* class_init */
     98     NULL,                       /* class_destroy */
     99     NULL,                       /* class_data */
    100     0,                          /* instance_size */
    101     0,                          /* n_preallocs */
    102     NULL,                       /* instance_init */
    103     &flags_enum_value_table,    /* value_table */
    104   };
    105   static const GTypeFundamentalInfo finfo = {
    106     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
    107   };
    108   GType type;
    109 
    110   g_return_if_fail (initialized == FALSE);
    111   initialized = TRUE;
    112 
    113   /* G_TYPE_ENUM
    114    */
    115   info.class_size = sizeof (GEnumClass);
    116   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
    117 				      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
    118   g_assert (type == G_TYPE_ENUM);
    119 
    120   /* G_TYPE_FLAGS
    121    */
    122   info.class_size = sizeof (GFlagsClass);
    123   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
    124 				      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
    125   g_assert (type == G_TYPE_FLAGS);
    126 }
    127 
    128 static void
    129 value_flags_enum_init (GValue *value)
    130 {
    131   value->data[0].v_long = 0;
    132 }
    133 
    134 static void
    135 value_flags_enum_copy_value (const GValue *src_value,
    136 			     GValue	  *dest_value)
    137 {
    138   dest_value->data[0].v_long = src_value->data[0].v_long;
    139 }
    140 
    141 static gchar*
    142 value_flags_enum_collect_value (GValue      *value,
    143 				guint        n_collect_values,
    144 				GTypeCValue *collect_values,
    145 				guint        collect_flags)
    146 {
    147   value->data[0].v_long = collect_values[0].v_int;
    148 
    149   return NULL;
    150 }
    151 
    152 static gchar*
    153 value_flags_enum_lcopy_value (const GValue *value,
    154 			      guint         n_collect_values,
    155 			      GTypeCValue  *collect_values,
    156 			      guint         collect_flags)
    157 {
    158   gint *int_p = collect_values[0].v_pointer;
    159 
    160   if (!int_p)
    161     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
    162 
    163   *int_p = value->data[0].v_long;
    164 
    165   return NULL;
    166 }
    167 
    168 /**
    169  * g_enum_register_static:
    170  * @name: A nul-terminated string used as the name of the new type.
    171  * @const_static_values: An array of #GEnumValue structs for the possible
    172  *  enumeration values. The array is terminated by a struct with all
    173  *  members being 0. GObject keeps a reference to the data, so it cannot
    174  *  be stack-allocated.
    175  *
    176  * Registers a new static enumeration type with the name @name.
    177  *
    178  * It is normally more convenient to let <link
    179  * linkend="glib-mkenums">glib-mkenums</link> generate a
    180  * my_enum_get_type() function from a usual C enumeration definition
    181  * than to write one yourself using g_enum_register_static().
    182  *
    183  * Returns: The new type identifier.
    184  */
    185 GType
    186 g_enum_register_static (const gchar	 *name,
    187 			const GEnumValue *const_static_values)
    188 {
    189   GTypeInfo enum_type_info = {
    190     sizeof (GEnumClass), /* class_size */
    191     NULL,                /* base_init */
    192     NULL,                /* base_finalize */
    193     (GClassInitFunc) g_enum_class_init,
    194     NULL,                /* class_finalize */
    195     NULL,                /* class_data */
    196     0,                   /* instance_size */
    197     0,                   /* n_preallocs */
    198     NULL,                /* instance_init */
    199     NULL,		 /* value_table */
    200   };
    201   GType type;
    202 
    203   g_return_val_if_fail (name != NULL, 0);
    204   g_return_val_if_fail (const_static_values != NULL, 0);
    205 
    206   enum_type_info.class_data = const_static_values;
    207 
    208   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
    209 
    210   return type;
    211 }
    212 
    213 /**
    214  * g_flags_register_static:
    215  * @name: A nul-terminated string used as the name of the new type.
    216  * @const_static_values: An array of #GFlagsValue structs for the possible
    217  *  flags values. The array is terminated by a struct with all members being 0.
    218  *  GObject keeps a reference to the data, so it cannot be stack-allocated.
    219  *
    220  * Registers a new static flags type with the name @name.
    221  *
    222  * It is normally more convenient to let <link
    223  * linkend="glib-mkenums">glib-mkenums</link> generate a
    224  * my_flags_get_type() function from a usual C enumeration definition
    225  * than to write one yourself using g_flags_register_static().
    226  *
    227  * Returns: The new type identifier.
    228  */
    229 GType
    230 g_flags_register_static (const gchar	   *name,
    231 			 const GFlagsValue *const_static_values)
    232 {
    233   GTypeInfo flags_type_info = {
    234     sizeof (GFlagsClass), /* class_size */
    235     NULL,                 /* base_init */
    236     NULL,                 /* base_finalize */
    237     (GClassInitFunc) g_flags_class_init,
    238     NULL,                 /* class_finalize */
    239     NULL,                 /* class_data */
    240     0,                    /* instance_size */
    241     0,                    /* n_preallocs */
    242     NULL,                 /* instance_init */
    243     NULL,		  /* value_table */
    244   };
    245   GType type;
    246 
    247   g_return_val_if_fail (name != NULL, 0);
    248   g_return_val_if_fail (const_static_values != NULL, 0);
    249 
    250   flags_type_info.class_data = const_static_values;
    251 
    252   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
    253 
    254   return type;
    255 }
    256 
    257 /**
    258  * g_enum_complete_type_info:
    259  * @g_enum_type: the type identifier of the type being completed
    260  * @info: the #GTypeInfo struct to be filled in
    261  * @const_values: An array of #GEnumValue structs for the possible
    262  *  enumeration values. The array is terminated by a struct with all
    263  *  members being 0.
    264  *
    265  * This function is meant to be called from the complete_type_info()
    266  * function of a #GTypePlugin implementation, as in the following
    267  * example:
    268  *
    269  * |[
    270  * static void
    271  * my_enum_complete_type_info (GTypePlugin     *plugin,
    272  *                             GType            g_type,
    273  *                             GTypeInfo       *info,
    274  *                             GTypeValueTable *value_table)
    275  * {
    276  *   static const GEnumValue values[] = {
    277  *     { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" },
    278  *     { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" },
    279  *     { 0, NULL, NULL }
    280  *   };
    281  *
    282  *   g_enum_complete_type_info (type, info, values);
    283  * }
    284  * ]|
    285  */
    286 void
    287 g_enum_complete_type_info (GType	     g_enum_type,
    288 			   GTypeInfo	    *info,
    289 			   const GEnumValue *const_values)
    290 {
    291   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
    292   g_return_if_fail (info != NULL);
    293   g_return_if_fail (const_values != NULL);
    294 
    295   info->class_size = sizeof (GEnumClass);
    296   info->base_init = NULL;
    297   info->base_finalize = NULL;
    298   info->class_init = (GClassInitFunc) g_enum_class_init;
    299   info->class_finalize = NULL;
    300   info->class_data = const_values;
    301 }
    302 
    303 /**
    304  * g_flags_complete_type_info:
    305  * @g_flags_type: the type identifier of the type being completed
    306  * @info: the #GTypeInfo struct to be filled in
    307  * @const_values: An array of #GFlagsValue structs for the possible
    308  *  enumeration values. The array is terminated by a struct with all
    309  *  members being 0.
    310  *
    311  * This function is meant to be called from the complete_type_info()
    312  * function of a #GTypePlugin implementation, see the example for
    313  * g_enum_complete_type_info() above.
    314  */
    315 void
    316 g_flags_complete_type_info (GType	       g_flags_type,
    317 			    GTypeInfo	      *info,
    318 			    const GFlagsValue *const_values)
    319 {
    320   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
    321   g_return_if_fail (info != NULL);
    322   g_return_if_fail (const_values != NULL);
    323 
    324   info->class_size = sizeof (GFlagsClass);
    325   info->base_init = NULL;
    326   info->base_finalize = NULL;
    327   info->class_init = (GClassInitFunc) g_flags_class_init;
    328   info->class_finalize = NULL;
    329   info->class_data = const_values;
    330 }
    331 
    332 static void
    333 g_enum_class_init (GEnumClass *class,
    334 		   gpointer    class_data)
    335 {
    336   g_return_if_fail (G_IS_ENUM_CLASS (class));
    337 
    338   class->minimum = 0;
    339   class->maximum = 0;
    340   class->n_values = 0;
    341   class->values = class_data;
    342 
    343   if (class->values)
    344     {
    345       GEnumValue *values;
    346 
    347       class->minimum = class->values->value;
    348       class->maximum = class->values->value;
    349       for (values = class->values; values->value_name; values++)
    350 	{
    351 	  class->minimum = MIN (class->minimum, values->value);
    352 	  class->maximum = MAX (class->maximum, values->value);
    353 	  class->n_values++;
    354 	}
    355     }
    356 }
    357 
    358 static void
    359 g_flags_class_init (GFlagsClass *class,
    360 		    gpointer	 class_data)
    361 {
    362   g_return_if_fail (G_IS_FLAGS_CLASS (class));
    363 
    364   class->mask = 0;
    365   class->n_values = 0;
    366   class->values = class_data;
    367 
    368   if (class->values)
    369     {
    370       GFlagsValue *values;
    371 
    372       for (values = class->values; values->value_name; values++)
    373 	{
    374 	  class->mask |= values->value;
    375 	  class->n_values++;
    376 	}
    377     }
    378 }
    379 
    380 /**
    381  * g_enum_get_value_by_name:
    382  * @enum_class: a #GEnumClass
    383  * @name: the name to look up
    384  *
    385  * Looks up a #GEnumValue by name.
    386  *
    387  * Returns: the #GEnumValue with name @name, or %NULL if the
    388  *          enumeration doesn't have a member with that name
    389  */
    390 GEnumValue*
    391 g_enum_get_value_by_name (GEnumClass  *enum_class,
    392 			  const gchar *name)
    393 {
    394   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
    395   g_return_val_if_fail (name != NULL, NULL);
    396 
    397   if (enum_class->n_values)
    398     {
    399       GEnumValue *enum_value;
    400 
    401       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
    402 	if (strcmp (name, enum_value->value_name) == 0)
    403 	  return enum_value;
    404     }
    405 
    406   return NULL;
    407 }
    408 
    409 /**
    410  * g_flags_get_value_by_name:
    411  * @flags_class: a #GFlagsClass
    412  * @name: the name to look up
    413  *
    414  * Looks up a #GFlagsValue by name.
    415  *
    416  * Returns: the #GFlagsValue with name @name, or %NULL if there is no
    417  *          flag with that name
    418  */
    419 GFlagsValue*
    420 g_flags_get_value_by_name (GFlagsClass *flags_class,
    421 			   const gchar *name)
    422 {
    423   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
    424   g_return_val_if_fail (name != NULL, NULL);
    425 
    426   if (flags_class->n_values)
    427     {
    428       GFlagsValue *flags_value;
    429 
    430       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
    431 	if (strcmp (name, flags_value->value_name) == 0)
    432 	  return flags_value;
    433     }
    434 
    435   return NULL;
    436 }
    437 
    438 /**
    439  * g_enum_get_value_by_nick:
    440  * @enum_class: a #GEnumClass
    441  * @nick: the nickname to look up
    442  *
    443  * Looks up a #GEnumValue by nickname.
    444  *
    445  * Returns: the #GEnumValue with nickname @nick, or %NULL if the
    446  *          enumeration doesn't have a member with that nickname
    447  */
    448 GEnumValue*
    449 g_enum_get_value_by_nick (GEnumClass  *enum_class,
    450 			  const gchar *nick)
    451 {
    452   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
    453   g_return_val_if_fail (nick != NULL, NULL);
    454 
    455   if (enum_class->n_values)
    456     {
    457       GEnumValue *enum_value;
    458 
    459       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
    460 	if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
    461 	  return enum_value;
    462     }
    463 
    464   return NULL;
    465 }
    466 
    467 /**
    468  * g_flags_get_value_by_nick:
    469  * @flags_class: a #GFlagsClass
    470  * @nick: the nickname to look up
    471  *
    472  * Looks up a #GFlagsValue by nickname.
    473  *
    474  * Returns: the #GFlagsValue with nickname @nick, or %NULL if there is
    475  *          no flag with that nickname
    476  */
    477 GFlagsValue*
    478 g_flags_get_value_by_nick (GFlagsClass *flags_class,
    479 			   const gchar *nick)
    480 {
    481   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
    482   g_return_val_if_fail (nick != NULL, NULL);
    483 
    484   if (flags_class->n_values)
    485     {
    486       GFlagsValue *flags_value;
    487 
    488       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
    489 	if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
    490 	  return flags_value;
    491     }
    492 
    493   return NULL;
    494 }
    495 
    496 /**
    497  * g_enum_get_value:
    498  * @enum_class: a #GEnumClass
    499  * @value: the value to look up
    500  *
    501  * Returns the #GEnumValue for a value.
    502  *
    503  * Returns: the #GEnumValue for @value, or %NULL if @value is not a
    504  *          member of the enumeration
    505  */
    506 GEnumValue*
    507 g_enum_get_value (GEnumClass *enum_class,
    508 		  gint	      value)
    509 {
    510   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
    511 
    512   if (enum_class->n_values)
    513     {
    514       GEnumValue *enum_value;
    515 
    516       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
    517 	if (enum_value->value == value)
    518 	  return enum_value;
    519     }
    520 
    521   return NULL;
    522 }
    523 
    524 /**
    525  * g_flags_get_first_value:
    526  * @flags_class: a #GFlagsClass
    527  * @value: the value
    528  *
    529  * Returns the first #GFlagsValue which is set in @value.
    530  *
    531  * Returns: the first #GFlagsValue which is set in @value, or %NULL if
    532  *          none is set
    533  */
    534 GFlagsValue*
    535 g_flags_get_first_value (GFlagsClass *flags_class,
    536 			 guint	      value)
    537 {
    538   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
    539 
    540   if (flags_class->n_values)
    541     {
    542       GFlagsValue *flags_value;
    543 
    544       if (value == 0)
    545         {
    546           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
    547             if (flags_value->value == 0)
    548               return flags_value;
    549         }
    550       else
    551         {
    552           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
    553             if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
    554               return flags_value;
    555         }
    556     }
    557 
    558   return NULL;
    559 }
    560 
    561 /**
    562  * g_value_set_enum:
    563  * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
    564  * @v_enum: enum value to be set
    565  *
    566  * Set the contents of a %G_TYPE_ENUM #GValue to @v_enum.
    567  */
    568 void
    569 g_value_set_enum (GValue *value,
    570 		  gint    v_enum)
    571 {
    572   g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
    573 
    574   value->data[0].v_long = v_enum;
    575 }
    576 
    577 /**
    578  * g_value_get_enum:
    579  * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
    580  *
    581  * Get the contents of a %G_TYPE_ENUM #GValue.
    582  *
    583  * Returns: enum contents of @value
    584  */
    585 gint
    586 g_value_get_enum (const GValue *value)
    587 {
    588   g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
    589 
    590   return value->data[0].v_long;
    591 }
    592 
    593 /**
    594  * g_value_set_flags:
    595  * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
    596  * @v_flags: flags value to be set
    597  *
    598  * Set the contents of a %G_TYPE_FLAGS #GValue to @v_flags.
    599  */
    600 void
    601 g_value_set_flags (GValue *value,
    602 		   guint   v_flags)
    603 {
    604   g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
    605 
    606   value->data[0].v_ulong = v_flags;
    607 }
    608 
    609 /**
    610  * g_value_get_flags:
    611  * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
    612  *
    613  * Get the contents of a %G_TYPE_FLAGS #GValue.
    614  *
    615  * Returns: flags contents of @value
    616  */
    617 guint
    618 g_value_get_flags (const GValue *value)
    619 {
    620   g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
    621 
    622   return value->data[0].v_ulong;
    623 }
    624 
    625 #define __G_ENUMS_C__
    626 #include "gobjectaliasdef.c"
    627