1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: Enum implementation
3 *
4 * Copyright (C) 2005 Matthias Clasen
5 * Copyright (C) 2008,2009 Red Hat, Inc.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
23 */
24
25 #include "config.h"
26
27 #include <glib.h>
28
29 #include <girepository/girepository.h>
30 #include "gibaseinfo-private.h"
31 #include "girepository-private.h"
32 #include "gitypelib-internal.h"
33 #include "gienuminfo.h"
34
35 /**
36 * GIEnumInfo:
37 *
38 * A `GIEnumInfo` represents an enumeration.
39 *
40 * The `GIEnumInfo` contains a set of values (each a
41 * [class@GIRepository.ValueInfo]) and a type.
42 *
43 * The [class@GIRepository.ValueInfo] for a value is fetched by calling
44 * [method@GIRepository.EnumInfo.get_value] on a `GIEnumInfo`.
45 *
46 * Since: 2.80
47 */
48
49 /**
50 * gi_enum_info_get_n_values:
51 * @info: a #GIEnumInfo
52 *
53 * Obtain the number of values this enumeration contains.
54 *
55 * Returns: the number of enumeration values
56 * Since: 2.80
57 */
58 guint
59 gi_enum_info_get_n_values (GIEnumInfo *info)
60 {
61 GIRealInfo *rinfo = (GIRealInfo *)info;
62 EnumBlob *blob;
63
64 g_return_val_if_fail (info != NULL, 0);
65 g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0);
66
67 blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
68
69 return blob->n_values;
70 }
71
72 /**
73 * gi_enum_info_get_error_domain:
74 * @info: a #GIEnumInfo
75 *
76 * Obtain the string form of the quark for the error domain associated with
77 * this enum, if any.
78 *
79 * Returns: (transfer none) (nullable): the string form of the error domain
80 * associated with this enum, or `NULL`.
81 * Since: 2.80
82 */
83 const gchar *
84 gi_enum_info_get_error_domain (GIEnumInfo *info)
85 {
86 GIRealInfo *rinfo = (GIRealInfo *)info;
87 EnumBlob *blob;
88
89 g_return_val_if_fail (info != NULL, 0);
90 g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0);
91
92 blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
93
94 if (blob->error_domain)
95 return gi_typelib_get_string (rinfo->typelib, blob->error_domain);
96 else
97 return NULL;
98 }
99
100 /**
101 * gi_enum_info_get_value:
102 * @info: a #GIEnumInfo
103 * @n: index of value to fetch
104 *
105 * Obtain a value for this enumeration.
106 *
107 * Returns: (transfer full): the enumeration value, free the struct with
108 * [method@GIRepository.BaseInfo.unref] when done.
109 * Since: 2.80
110 */
111 GIValueInfo *
112 gi_enum_info_get_value (GIEnumInfo *info,
113 guint n)
114 {
115 GIRealInfo *rinfo = (GIRealInfo *)info;
116 Header *header;
117 gint offset;
118
119 g_return_val_if_fail (info != NULL, NULL);
120 g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL);
121
122 header = (Header *)rinfo->typelib->data;
123 offset = rinfo->offset + header->enum_blob_size
124 + n * header->value_blob_size;
125
126 return (GIValueInfo *) gi_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset);
127 }
128
129 /**
130 * gi_enum_info_get_n_methods:
131 * @info: a #GIEnumInfo
132 *
133 * Obtain the number of methods that this enum type has.
134 *
135 * Returns: number of methods
136 * Since: 2.80
137 */
138 guint
139 gi_enum_info_get_n_methods (GIEnumInfo *info)
140 {
141 GIRealInfo *rinfo = (GIRealInfo *)info;
142 EnumBlob *blob;
143
144 g_return_val_if_fail (info != NULL, 0);
145 g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0);
146
147 blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
148
149 return blob->n_methods;
150 }
151
152 /**
153 * gi_enum_info_get_method:
154 * @info: a #GIEnumInfo
155 * @n: index of method to get
156 *
157 * Obtain an enum type method at index @n.
158 *
159 * Returns: (transfer full): the [class@GIRepository.FunctionInfo]. Free the
160 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
161 * Since: 2.80
162 */
163 GIFunctionInfo *
164 gi_enum_info_get_method (GIEnumInfo *info,
165 guint n)
166 {
167 gint offset;
168 GIRealInfo *rinfo = (GIRealInfo *)info;
169 Header *header;
170 EnumBlob *blob;
171
172 g_return_val_if_fail (info != NULL, NULL);
173 g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL);
174
175 header = (Header *)rinfo->typelib->data;
176 blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
177
178 offset = rinfo->offset + header->enum_blob_size
179 + blob->n_values * header->value_blob_size
180 + n * header->function_blob_size;
181
182 return (GIFunctionInfo *) gi_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
183 rinfo->typelib, offset);
184 }
185
186 /**
187 * gi_enum_info_get_storage_type:
188 * @info: a #GIEnumInfo
189 *
190 * Obtain the tag of the type used for the enum in the C ABI. This will
191 * will be a signed or unsigned integral type.
192 *
193 * Note that in the current implementation the width of the type is
194 * computed correctly, but the signed or unsigned nature of the type
195 * may not match the sign of the type used by the C compiler.
196 *
197 * Returns: the storage type for the enumeration
198 * Since: 2.80
199 */
200 GITypeTag
201 gi_enum_info_get_storage_type (GIEnumInfo *info)
202 {
203 GIRealInfo *rinfo = (GIRealInfo *)info;
204 EnumBlob *blob;
205
206 g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN);
207 g_return_val_if_fail (GI_IS_ENUM_INFO (info), GI_TYPE_TAG_BOOLEAN);
208
209 blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
210
211 return blob->storage_type;
212 }
213
214 void
215 gi_enum_info_class_init (gpointer g_class,
216 gpointer class_data)
217 {
218 GIBaseInfoClass *info_class = g_class;
219
220 info_class->info_type = GI_INFO_TYPE_ENUM;
221 }
222
223 /**
224 * GIValueInfo:
225 *
226 * A `GIValueInfo` represents a value in an enumeration.
227 *
228 * The `GIValueInfo` is fetched by calling
229 * [method@GIRepository.EnumInfo.get_value] on a [class@GIRepository.EnumInfo].
230 *
231 * Since: 2.80
232 */
233
234 /**
235 * gi_value_info_get_value:
236 * @info: a #GIValueInfo
237 *
238 * Obtain the enumeration value of the `GIValueInfo`.
239 *
240 * Returns: the enumeration value. This will always be representable
241 * as a 32-bit signed or unsigned value. The use of `gint64` as the
242 * return type is to allow both.
243 * Since: 2.80
244 */
245 gint64
246 gi_value_info_get_value (GIValueInfo *info)
247 {
248 GIRealInfo *rinfo = (GIRealInfo *)info;
249 ValueBlob *blob;
250
251 g_return_val_if_fail (info != NULL, -1);
252 g_return_val_if_fail (GI_IS_VALUE_INFO (info), -1);
253
254 blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
255
256 if (blob->unsigned_value)
257 return (gint64)(guint32)blob->value;
258 else
259 return (gint64)blob->value;
260 }
261
262 void
263 gi_value_info_class_init (gpointer g_class,
264 gpointer class_data)
265 {
266 GIBaseInfoClass *info_class = g_class;
267
268 info_class->info_type = GI_INFO_TYPE_VALUE;
269 }