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