Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : * GObject introspection: Struct 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 <string.h>
28 : :
29 : : #include <glib.h>
30 : :
31 : : #include <girepository/girepository.h>
32 : : #include "gibaseinfo-private.h"
33 : : #include "girepository-private.h"
34 : : #include "gitypelib-internal.h"
35 : : #include "gistructinfo.h"
36 : :
37 : : /**
38 : : * GIStructInfo:
39 : : *
40 : : * `GIStructInfo` represents a generic C structure type.
41 : : *
42 : : * A structure has methods and fields.
43 : : *
44 : : * Since: 2.80
45 : : */
46 : :
47 : : /**
48 : : * gi_struct_info_get_n_fields:
49 : : * @info: a #GIStructInfo
50 : : *
51 : : * Obtain the number of fields this structure has.
52 : : *
53 : : * Returns: number of fields
54 : : * Since: 2.80
55 : : */
56 : : unsigned int
57 : 16 : gi_struct_info_get_n_fields (GIStructInfo *info)
58 : : {
59 : 16 : GIRealInfo *rinfo = (GIRealInfo *)info;
60 : 16 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
61 : :
62 : 16 : return blob->n_fields;
63 : : }
64 : :
65 : : /**
66 : : * gi_struct_info_get_field_offset:
67 : : * @info: a #GIStructInfo
68 : : * @n: index of queried field
69 : : *
70 : : * Obtain the offset of the specified field.
71 : : *
72 : : * Returns: field offset, in bytes
73 : : * Since: 2.80
74 : : */
75 : : static size_t
76 : 19 : gi_struct_get_field_offset (GIStructInfo *info,
77 : : uint16_t n)
78 : : {
79 : 19 : GIRealInfo *rinfo = (GIRealInfo *)info;
80 : 19 : Header *header = (Header *)rinfo->typelib->data;
81 : 19 : size_t offset = rinfo->offset + header->struct_blob_size;
82 : : FieldBlob *field_blob;
83 : :
84 : 143 : for (uint16_t i = 0; i < n; i++)
85 : : {
86 : 124 : field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
87 : 124 : offset += header->field_blob_size;
88 : 124 : if (field_blob->has_embedded_type)
89 : 63 : offset += header->callback_blob_size;
90 : : }
91 : :
92 : 19 : return offset;
93 : : }
94 : :
95 : : /**
96 : : * gi_struct_info_get_field:
97 : : * @info: a #GIStructInfo
98 : : * @n: a field index
99 : : *
100 : : * Obtain the type information for field with specified index.
101 : : *
102 : : * Returns: (transfer full): The [class@GIRepository.FieldInfo]. Free it with
103 : : * [method@GIRepository.BaseInfo.unref] when done.
104 : : * Since: 2.80
105 : : */
106 : : GIFieldInfo *
107 : 15 : gi_struct_info_get_field (GIStructInfo *info,
108 : : unsigned int n)
109 : : {
110 : 15 : GIRealInfo *rinfo = (GIRealInfo *)info;
111 : :
112 : 15 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
113 : :
114 : 15 : return (GIFieldInfo *) gi_base_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
115 : : gi_struct_get_field_offset (info, n));
116 : : }
117 : :
118 : : /**
119 : : * gi_struct_info_find_field:
120 : : * @info: a #GIStructInfo
121 : : * @name: a field name
122 : : *
123 : : * Obtain the type information for field named @name.
124 : : *
125 : : * Returns: (transfer full) (nullable): The [class@GIRepository.FieldInfo], or
126 : : * `NULL` if not found. Free it with [method@GIRepository.BaseInfo.unref] when
127 : : * done.
128 : : * Since: 2.80
129 : : */
130 : : GIFieldInfo *
131 : 19 : gi_struct_info_find_field (GIStructInfo *info,
132 : : const char *name)
133 : : {
134 : 19 : GIRealInfo *rinfo = (GIRealInfo *)info;
135 : 19 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
136 : 19 : Header *header = (Header *)rinfo->typelib->data;
137 : 19 : size_t offset = rinfo->offset + header->struct_blob_size;
138 : :
139 : 147 : for (size_t i = 0; i < blob->n_fields; i++)
140 : : {
141 : 146 : FieldBlob *field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
142 : 146 : const char *fname = (const char *)&rinfo->typelib->data[field_blob->name];
143 : :
144 : 146 : if (strcmp (name, fname) == 0)
145 : : {
146 : 18 : return (GIFieldInfo *) gi_base_info_new (GI_INFO_TYPE_FIELD,
147 : : (GIBaseInfo* )info,
148 : : rinfo->typelib,
149 : : offset);
150 : : }
151 : :
152 : 128 : offset += header->field_blob_size;
153 : 128 : if (field_blob->has_embedded_type)
154 : 70 : offset += header->callback_blob_size;
155 : : }
156 : :
157 : 1 : return NULL;
158 : : }
159 : :
160 : : /**
161 : : * gi_struct_info_get_n_methods:
162 : : * @info: a #GIStructInfo
163 : : *
164 : : * Obtain the number of methods this structure has.
165 : : *
166 : : * Returns: number of methods
167 : : * Since: 2.80
168 : : */
169 : : unsigned int
170 : 0 : gi_struct_info_get_n_methods (GIStructInfo *info)
171 : : {
172 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
173 : 0 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
174 : :
175 : 0 : return blob->n_methods;
176 : : }
177 : :
178 : : /**
179 : : * gi_struct_info_get_method:
180 : : * @info: a #GIStructInfo
181 : : * @n: a method index
182 : : *
183 : : * Obtain the type information for method with specified index.
184 : : *
185 : : * Returns: (transfer full): The [class@GIRepository.FunctionInfo]. Free it with
186 : : * [method@GIRepository.BaseInfo.unref] when done.
187 : : * Since: 2.80
188 : : */
189 : : GIFunctionInfo *
190 : 0 : gi_struct_info_get_method (GIStructInfo *info,
191 : : unsigned int n)
192 : : {
193 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
194 : 0 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
195 : 0 : Header *header = (Header *)rinfo->typelib->data;
196 : : size_t offset;
197 : :
198 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
199 : :
200 : 0 : offset = gi_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size;
201 : 0 : return (GIFunctionInfo *) gi_base_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
202 : : rinfo->typelib, offset);
203 : : }
204 : :
205 : : /**
206 : : * gi_struct_info_find_method:
207 : : * @info: a #GIStructInfo
208 : : * @name: a method name
209 : : *
210 : : * Obtain the type information for method named @name.
211 : : *
212 : : * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
213 : : * or `NULL` if none was found. Free it with
214 : : * [method@GIRepository.BaseInfo.unref] when done.
215 : : * Since: 2.80
216 : : */
217 : : GIFunctionInfo *
218 : 4 : gi_struct_info_find_method (GIStructInfo *info,
219 : : const char *name)
220 : : {
221 : : size_t offset;
222 : 4 : GIRealInfo *rinfo = (GIRealInfo *)info;
223 : 4 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
224 : :
225 : 4 : offset = gi_struct_get_field_offset (info, blob->n_fields);
226 : 4 : return gi_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
227 : : }
228 : :
229 : : /**
230 : : * gi_struct_info_get_size:
231 : : * @info: a #GIStructInfo
232 : : *
233 : : * Obtain the total size of the structure.
234 : : *
235 : : * Returns: size of the structure, in bytes
236 : : * Since: 2.80
237 : : */
238 : : size_t
239 : 1 : gi_struct_info_get_size (GIStructInfo *info)
240 : : {
241 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
242 : 1 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
243 : :
244 : 1 : return blob->size;
245 : : }
246 : :
247 : : /**
248 : : * gi_struct_info_get_alignment:
249 : : * @info: a #GIStructInfo
250 : : *
251 : : * Obtain the required alignment of the structure.
252 : : *
253 : : * Returns: required alignment, in bytes
254 : : * Since: 2.80
255 : : */
256 : : size_t
257 : 0 : gi_struct_info_get_alignment (GIStructInfo *info)
258 : : {
259 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
260 : 0 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
261 : :
262 : 0 : return blob->alignment;
263 : : }
264 : :
265 : : /**
266 : : * gi_struct_info_is_foreign:
267 : : * @info: a #GIStructInfo
268 : : *
269 : : * Gets whether the structure is foreign, i.e. if it’s expected to be overridden
270 : : * by a native language binding instead of relying of introspected bindings.
271 : : *
272 : : * Returns: `TRUE` if the structure is foreign
273 : : * Since: 2.80
274 : : */
275 : : gboolean
276 : 0 : gi_struct_info_is_foreign (GIStructInfo *info)
277 : : {
278 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
279 : 0 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
280 : :
281 : 0 : return blob->foreign;
282 : : }
283 : :
284 : : /**
285 : : * gi_struct_info_is_gtype_struct:
286 : : * @info: a #GIStructInfo
287 : : *
288 : : * Return true if this structure represents the ‘class structure’ for some
289 : : * [class@GObject.Object] or `GInterface`.
290 : : *
291 : : * This function is mainly useful to hide this kind of structure from generated
292 : : * public APIs.
293 : : *
294 : : * Returns: `TRUE` if this is a class struct, `FALSE` otherwise
295 : : * Since: 2.80
296 : : */
297 : : gboolean
298 : 4 : gi_struct_info_is_gtype_struct (GIStructInfo *info)
299 : : {
300 : 4 : GIRealInfo *rinfo = (GIRealInfo *)info;
301 : 4 : StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
302 : :
303 : 4 : return blob->is_gtype_struct;
304 : : }
305 : :
306 : : /**
307 : : * gi_struct_info_get_copy_function_name:
308 : : * @info: a struct information blob
309 : : *
310 : : * Retrieves the name of the copy function for @info, if any is set.
311 : : *
312 : : * Returns: (transfer none) (nullable): the name of the copy function, or `NULL`
313 : : * if the structure has no copy function
314 : : * Since: 2.80
315 : : */
316 : : const char *
317 : 0 : gi_struct_info_get_copy_function_name (GIStructInfo *info)
318 : : {
319 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
320 : : StructBlob *blob;
321 : :
322 : 0 : g_return_val_if_fail (info != NULL, NULL);
323 : 0 : g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL);
324 : :
325 : 0 : blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
326 : :
327 : 0 : if (blob->copy_func)
328 : 0 : return gi_typelib_get_string (rinfo->typelib, blob->copy_func);
329 : :
330 : 0 : return NULL;
331 : : }
332 : :
333 : : /**
334 : : * gi_struct_info_get_free_function_name:
335 : : * @info: a struct information blob
336 : : *
337 : : * Retrieves the name of the free function for @info, if any is set.
338 : : *
339 : : * Returns: (transfer none) (nullable): the name of the free function, or `NULL`
340 : : * if the structure has no free function
341 : : * Since: 2.80
342 : : */
343 : : const char *
344 : 0 : gi_struct_info_get_free_function_name (GIStructInfo *info)
345 : : {
346 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
347 : : StructBlob *blob;
348 : :
349 : 0 : g_return_val_if_fail (info != NULL, NULL);
350 : 0 : g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL);
351 : :
352 : 0 : blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
353 : :
354 : 0 : if (blob->free_func)
355 : 0 : return gi_typelib_get_string (rinfo->typelib, blob->free_func);
356 : :
357 : 0 : return NULL;
358 : : }
359 : :
360 : : void
361 : 5 : gi_struct_info_class_init (gpointer g_class,
362 : : gpointer class_data)
363 : : {
364 : 5 : GIBaseInfoClass *info_class = g_class;
365 : :
366 : 5 : info_class->info_type = GI_INFO_TYPE_STRUCT;
367 : 5 : }
|