added newly added gobject/ headers.
[platform/upstream/glib.git] / gobject / genums.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998, 1999, 2000 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 #include        <string.h>
21
22 #include        "genums.h"
23
24 #include        "gvalue.h"
25 #include        "gvaluecollector.h"
26
27
28 /* --- prototypes --- */
29 static void     g_enum_class_init               (GEnumClass     *class,
30                                                  gpointer        class_data);
31 static void     g_flags_class_init              (GFlagsClass    *class,
32                                                  gpointer        class_data);
33 static void     value_flags_enum_init           (GValue         *value);
34 static void     value_flags_enum_copy_value     (const GValue   *src_value,
35                                                  GValue         *dest_value);
36 static gchar*   value_flags_enum_collect_value (GValue          *value,
37                                                 guint            nth_value,
38                                                 GType           *collect_type,
39                                                 GTypeCValue     *collect_value);
40 static gchar*   value_flags_enum_lcopy_value    (const GValue   *value,
41                                                  guint           nth_value,
42                                                  GType          *collect_type,
43                                                  GTypeCValue    *collect_value);
44
45
46 /* --- functions --- */
47 void
48 g_enum_types_init (void)        /* sync with gtype.c */
49 {
50   static gboolean initialized = FALSE;
51   static const GTypeValueTable flags_enum_value_table = {
52     value_flags_enum_init,        /* value_init */
53     NULL,                                 /* value_free */
54     value_flags_enum_copy_value,    /* value_copy */
55     NULL,                                 /* value_peek_pointer */
56     G_VALUE_COLLECT_INT,                  /* collect_type */
57     value_flags_enum_collect_value, /* collect_value */
58     G_VALUE_COLLECT_POINTER,      /* lcopy_type */
59     value_flags_enum_lcopy_value,   /* lcopy_value */
60   };
61   static GTypeInfo info = {
62     0,                          /* class_size */
63     NULL,                       /* base_init */
64     NULL,                       /* base_destroy */
65     NULL,                       /* class_init */
66     NULL,                       /* class_destroy */
67     NULL,                       /* class_data */
68     0,                          /* instance_size */
69     0,                          /* n_preallocs */
70     NULL,                       /* instance_init */
71     &flags_enum_value_table,    /* value_table */
72   };
73   static const GTypeFundamentalInfo finfo = {
74     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
75   };
76   GType type;
77   
78   g_return_if_fail (initialized == FALSE);
79   initialized = TRUE;
80   
81   /* G_TYPE_ENUM
82    */
83   info.class_size = sizeof (GEnumClass);
84   type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &info, &finfo, G_TYPE_FLAG_ABSTRACT);
85   g_assert (type == G_TYPE_ENUM);
86   
87   /* G_TYPE_FLAGS
88    */
89   info.class_size = sizeof (GFlagsClass);
90   type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &info, &finfo, G_TYPE_FLAG_ABSTRACT);
91   g_assert (type == G_TYPE_FLAGS);
92 }
93
94 static void
95 value_flags_enum_init (GValue *value)
96 {
97   value->data[0].v_long = 0;
98 }
99
100 static void
101 value_flags_enum_copy_value (const GValue *src_value,
102                              GValue       *dest_value)
103 {
104   dest_value->data[0].v_long = src_value->data[0].v_long;
105 }
106
107 static gchar*
108 value_flags_enum_collect_value (GValue      *value,
109                                 guint        nth_value,
110                                 GType       *collect_type,
111                                 GTypeCValue *collect_value)
112 {
113   value->data[0].v_long = collect_value->v_int;
114   
115   *collect_type = 0;
116   return NULL;
117 }
118
119 static gchar*
120 value_flags_enum_lcopy_value (const GValue *value,
121                               guint         nth_value,
122                               GType        *collect_type,
123                               GTypeCValue  *collect_value)
124 {
125   gint *int_p = collect_value->v_pointer;
126   
127   if (!int_p)
128     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
129   
130   *int_p = value->data[0].v_long;
131   
132   *collect_type = 0;
133   return NULL;
134 }
135
136 GType
137 g_enum_register_static (const gchar      *name,
138                         const GEnumValue *const_static_values)
139 {
140   GTypeInfo enum_type_info = {
141     sizeof (GEnumClass), /* class_size */
142     NULL,                /* base_init */
143     NULL,                /* base_finalize */
144     (GClassInitFunc) g_enum_class_init,
145     NULL,                /* class_finalize */
146     NULL,                /* class_data */
147     0,                   /* instance_size */
148     0,                   /* n_preallocs */
149     NULL,                /* instance_init */
150     NULL,                /* value_table */
151   };
152   GType type;
153   
154   g_return_val_if_fail (name != NULL, 0);
155   g_return_val_if_fail (const_static_values != NULL, 0);
156   
157   enum_type_info.class_data = const_static_values;
158   
159   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
160   
161   return type;
162 }
163
164 GType
165 g_flags_register_static (const gchar       *name,
166                          const GFlagsValue *const_static_values)
167 {
168   GTypeInfo flags_type_info = {
169     sizeof (GFlagsClass), /* class_size */
170     NULL,                 /* base_init */
171     NULL,                 /* base_finalize */
172     (GClassInitFunc) g_flags_class_init,
173     NULL,                 /* class_finalize */
174     NULL,                 /* class_data */
175     0,                    /* instance_size */
176     0,                    /* n_preallocs */
177     NULL,                 /* instance_init */
178     NULL,                 /* value_table */
179   };
180   GType type;
181   
182   g_return_val_if_fail (name != NULL, 0);
183   g_return_val_if_fail (const_static_values != NULL, 0);
184   
185   flags_type_info.class_data = const_static_values;
186   
187   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
188   
189   return type;
190 }
191
192 void
193 g_enum_complete_type_info (GType             g_enum_type,
194                            GTypeInfo        *info,
195                            const GEnumValue *const_values)
196 {
197   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
198   g_return_if_fail (info != NULL);
199   g_return_if_fail (const_values != NULL);
200   
201   info->class_size = sizeof (GEnumClass);
202   info->base_init = NULL;
203   info->base_finalize = NULL;
204   info->class_init = (GClassInitFunc) g_enum_class_init;
205   info->class_finalize = NULL;
206   info->class_data = const_values;
207 }
208
209 void
210 g_flags_complete_type_info (GType              g_flags_type,
211                             GTypeInfo         *info,
212                             const GFlagsValue *const_values)
213 {
214   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
215   g_return_if_fail (info != NULL);
216   g_return_if_fail (const_values != NULL);
217   
218   info->class_size = sizeof (GFlagsClass);
219   info->base_init = NULL;
220   info->base_finalize = NULL;
221   info->class_init = (GClassInitFunc) g_flags_class_init;
222   info->class_finalize = NULL;
223   info->class_data = const_values;
224 }
225
226 static void
227 g_enum_class_init (GEnumClass *class,
228                    gpointer    class_data)
229 {
230   g_return_if_fail (G_IS_ENUM_CLASS (class));
231   
232   class->minimum = 0;
233   class->maximum = 0;
234   class->n_values = 0;
235   class->values = class_data;
236   
237   if (class->values)
238     {
239       GEnumValue *values;
240       
241       class->minimum = class->values->value;
242       class->maximum = class->values->value;
243       for (values = class->values; values->value_name; values++)
244         {
245           class->minimum = MIN (class->minimum, values->value);
246           class->maximum = MAX (class->maximum, values->value);
247           class->n_values++;
248         }
249     }
250 }
251
252 static void
253 g_flags_class_init (GFlagsClass *class,
254                     gpointer     class_data)
255 {
256   g_return_if_fail (G_IS_FLAGS_CLASS (class));
257   
258   class->mask = 0;
259   class->n_values = 0;
260   class->values = class_data;
261   
262   if (class->values)
263     {
264       GFlagsValue *values;
265       
266       for (values = class->values; values->value_name; values++)
267         {
268           class->mask |= values->value;
269           class->n_values++;
270         }
271     }
272 }
273
274 GEnumValue*
275 g_enum_get_value_by_name (GEnumClass  *enum_class,
276                           const gchar *name)
277 {
278   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
279   g_return_val_if_fail (name != NULL, NULL);
280   
281   if (enum_class->n_values)
282     {
283       GEnumValue *enum_value;
284       
285       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
286         if (strcmp (name, enum_value->value_name) == 0)
287           return enum_value;
288     }
289   
290   return NULL;
291 }
292
293 GFlagsValue*
294 g_flags_get_value_by_name (GFlagsClass *flags_class,
295                            const gchar *name)
296 {
297   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
298   g_return_val_if_fail (name != NULL, NULL);
299   
300   if (flags_class->n_values)
301     {
302       GFlagsValue *flags_value;
303       
304       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
305         if (strcmp (name, flags_value->value_name) == 0)
306           return flags_value;
307     }
308   
309   return NULL;
310 }
311
312 GEnumValue*
313 g_enum_get_value_by_nick (GEnumClass  *enum_class,
314                           const gchar *nick)
315 {
316   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
317   g_return_val_if_fail (nick != NULL, NULL);
318   
319   if (enum_class->n_values)
320     {
321       GEnumValue *enum_value;
322       
323       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
324         if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
325           return enum_value;
326     }
327   
328   return NULL;
329 }
330
331 GFlagsValue*
332 g_flags_get_value_by_nick (GFlagsClass *flags_class,
333                            const gchar *nick)
334 {
335   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
336   g_return_val_if_fail (nick != NULL, NULL);
337   
338   if (flags_class->n_values)
339     {
340       GFlagsValue *flags_value;
341       
342       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
343         if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
344           return flags_value;
345     }
346   
347   return NULL;
348 }
349
350 GEnumValue*
351 g_enum_get_value (GEnumClass *enum_class,
352                   gint        value)
353 {
354   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
355   
356   if (enum_class->n_values)
357     {
358       GEnumValue *enum_value;
359       
360       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
361         if (enum_value->value == value)
362           return enum_value;
363     }
364   
365   return NULL;
366 }
367
368 GFlagsValue*
369 g_flags_get_first_value (GFlagsClass *flags_class,
370                          guint        value)
371 {
372   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
373   
374   if (flags_class->n_values)
375     {
376       GFlagsValue *flags_value;
377       
378       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
379         if ((flags_value->value & value) > 0)
380           return flags_value;
381     }
382   
383   return NULL;
384 }
385
386 void
387 g_value_set_enum (GValue *value,
388                   gint    v_enum)
389 {
390   g_return_if_fail (G_IS_VALUE_ENUM (value));
391   
392   value->data[0].v_long = v_enum;
393 }
394
395 gint
396 g_value_get_enum (const GValue *value)
397 {
398   g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0);
399   
400   return value->data[0].v_long;
401 }
402
403 void
404 g_value_set_flags (GValue *value,
405                    guint   v_flags)
406 {
407   g_return_if_fail (G_IS_VALUE_FLAGS (value));
408   
409   value->data[0].v_ulong = v_flags;
410 }
411
412 guint
413 g_value_get_flags (const GValue *value)
414 {
415   g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0);
416   
417   return value->data[0].v_ulong;
418 }