genums.c revision 397ad5881e972da23eccca1b20bbcfe2e8648f11
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
22/* --- prototypes --- */
23extern void	g_enum_types_init		(void);
24static void	g_enum_class_init		(GEnumClass	*class,
25						 gpointer	 class_data);
26static void	g_flags_class_init		(GFlagsClass	*class,
27						 gpointer	 class_data);
28
29
30/* --- functions --- */
31void
32g_enum_types_init (void)	/* sync with glib-gtype.c */
33{
34  static gboolean initialized = FALSE;
35  static const GTypeFundamentalInfo finfo = {
36    G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
37    0		/* n_collect_bytes */,
38    NULL	/* GTypeParamCollector */,
39  };
40  static GTypeInfo info = {
41    0	/* class_size */,
42    NULL	/* base_init */,
43    NULL	/* base_finalize */,
44    NULL	/* class_init */,
45    NULL	/* class_finalize */,
46    NULL	/* class_data */,
47  };
48  GType type;
49
50  g_return_if_fail (initialized == FALSE);
51  initialized = TRUE;
52
53  /* G_TYPE_ENUM
54   */
55  info.class_size = sizeof (GEnumClass);
56  type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &finfo, &info);
57  g_assert (type == G_TYPE_ENUM);
58
59  /* G_TYPE_FLAGS
60   */
61  info.class_size = sizeof (GFlagsClass);
62  type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &finfo, &info);
63  g_assert (type == G_TYPE_FLAGS);
64}
65
66GType
67g_enum_register_static (const gchar	 *name,
68			const GEnumValue *const_static_values)
69{
70  GTypeInfo enum_type_info = {
71    sizeof (GEnumClass),
72    NULL	/* base_init */,
73    NULL	/* base_finalize */,
74    (GClassInitFunc) g_enum_class_init,
75    NULL	/* class_finalize */,
76    NULL	/* class_data */,
77  };
78  GType type;
79
80  g_return_val_if_fail (name != NULL, 0);
81  g_return_val_if_fail (const_static_values != NULL, 0);
82
83  enum_type_info.class_data = const_static_values;
84
85  type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info);
86
87  return type;
88}
89
90GType
91g_flags_register_static (const gchar	   *name,
92			 const GFlagsValue *const_static_values)
93{
94  GTypeInfo flags_type_info = {
95    sizeof (GFlagsClass),
96    NULL	/* base_init */,
97    NULL	/* base_finalize */,
98    (GClassInitFunc) g_flags_class_init,
99    NULL	/* class_finalize */,
100    NULL	/* class_data */,
101  };
102  GType type;
103
104  g_return_val_if_fail (name != NULL, 0);
105  g_return_val_if_fail (const_static_values != NULL, 0);
106
107  flags_type_info.class_data = const_static_values;
108
109  type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info);
110
111  return type;
112}
113
114void
115g_enum_complete_type_info (GType	     g_enum_type,
116			   GTypeInfo	    *info,
117			   const GEnumValue *const_values)
118{
119  g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
120  g_return_if_fail (info != NULL);
121  g_return_if_fail (const_values != NULL);
122
123  info->class_size = sizeof (GEnumClass);
124  info->base_init = NULL;
125  info->base_finalize = NULL;
126  info->class_init = (GClassInitFunc) g_enum_class_init;
127  info->class_finalize = NULL;
128  info->class_data = const_values;
129}
130
131void
132g_flags_complete_type_info (GType	       g_flags_type,
133			    GTypeInfo	      *info,
134			    const GFlagsValue *const_values)
135{
136  g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
137  g_return_if_fail (info != NULL);
138  g_return_if_fail (const_values != NULL);
139
140  info->class_size = sizeof (GFlagsClass);
141  info->base_init = NULL;
142  info->base_finalize = NULL;
143  info->class_init = (GClassInitFunc) g_flags_class_init;
144  info->class_finalize = NULL;
145  info->class_data = const_values;
146}
147
148static void
149g_enum_class_init (GEnumClass *class,
150		   gpointer    class_data)
151{
152  g_return_if_fail (G_IS_ENUM_CLASS (class));
153
154  class->minimum = 0;
155  class->maximum = 0;
156  class->n_values = 0;
157  class->values = class_data;
158
159  if (class->values)
160    {
161      GEnumValue *values;
162
163      class->minimum = class->values->value;
164      class->maximum = class->values->value;
165      for (values = class->values; values->value_name; values++)
166	{
167	  class->minimum = MIN (class->minimum, values->value);
168	  class->maximum = MAX (class->maximum, values->value);
169	  class->n_values++;
170	}
171    }
172}
173
174static void
175g_flags_class_init (GFlagsClass *class,
176		    gpointer	 class_data)
177{
178  g_return_if_fail (G_IS_FLAGS_CLASS (class));
179
180  class->mask = 0;
181  class->n_values = 0;
182  class->values = class_data;
183
184  if (class->values)
185    {
186      GFlagsValue *values;
187
188      for (values = class->values; values->value_name; values++)
189	{
190	  class->mask |= values->value;
191	  class->n_values++;
192	}
193    }
194}
195
196GEnumValue*
197g_enum_get_value_by_name (GEnumClass  *enum_class,
198			  const gchar *name)
199{
200  g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
201  g_return_val_if_fail (name != NULL, NULL);
202
203  if (enum_class->n_values)
204    {
205      GEnumValue *enum_value;
206
207      for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
208	if (strcmp (name, enum_value->value_name) == 0)
209	  return enum_value;
210    }
211
212  return NULL;
213}
214
215GFlagsValue*
216g_flags_get_value_by_name (GFlagsClass *flags_class,
217			   const gchar *name)
218{
219  g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
220  g_return_val_if_fail (name != NULL, NULL);
221
222  if (flags_class->n_values)
223    {
224      GFlagsValue *flags_value;
225
226      for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
227	if (strcmp (name, flags_value->value_name) == 0)
228	  return flags_value;
229    }
230
231  return NULL;
232}
233
234GEnumValue*
235g_enum_get_value_by_nick (GEnumClass  *enum_class,
236			  const gchar *nick)
237{
238  g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
239  g_return_val_if_fail (nick != NULL, NULL);
240
241  if (enum_class->n_values)
242    {
243      GEnumValue *enum_value;
244
245      for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
246	if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
247	  return enum_value;
248    }
249
250  return NULL;
251}
252
253GFlagsValue*
254g_flags_get_value_by_nick (GFlagsClass *flags_class,
255			   const gchar *nick)
256{
257  g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
258  g_return_val_if_fail (nick != NULL, NULL);
259
260  if (flags_class->n_values)
261    {
262      GFlagsValue *flags_value;
263
264      for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
265	if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
266	  return flags_value;
267    }
268
269  return NULL;
270}
271
272GEnumValue*
273g_enum_get_value (GEnumClass *enum_class,
274		  gint	      value)
275{
276  g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
277
278  if (enum_class->n_values)
279    {
280      GEnumValue *enum_value;
281
282      for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
283	if (enum_value->value == value)
284	  return enum_value;
285    }
286
287  return NULL;
288}
289
290GFlagsValue*
291g_flags_get_first_value (GFlagsClass *flags_class,
292			 guint	      value)
293{
294  g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
295
296  if (flags_class->n_values)
297    {
298      GFlagsValue *flags_value;
299
300      for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
301	if ((flags_value->value & value) > 0)
302	  return flags_value;
303    }
304
305  return NULL;
306}
307