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