Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : * GObject introspection: Interface 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 "giinterfaceinfo.h"
34 : :
35 : : /**
36 : : * GIInterfaceInfo:
37 : : *
38 : : * `GIInterfaceInfo` represents a `GInterface` type.
39 : : *
40 : : * A `GInterface` has methods, fields, properties, signals,
41 : : * interfaces, constants, virtual functions and prerequisites.
42 : : *
43 : : * Since: 2.80
44 : : */
45 : :
46 : : /**
47 : : * gi_interface_info_get_n_prerequisites:
48 : : * @info: a #GIInterfaceInfo
49 : : *
50 : : * Obtain the number of prerequisites for this interface type.
51 : : *
52 : : * A prerequisite is another interface that needs to be implemented for
53 : : * interface, similar to a base class for [class@GObject.Object]s.
54 : : *
55 : : * Returns: number of prerequisites
56 : : * Since: 2.80
57 : : */
58 : : unsigned int
59 : 0 : gi_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
60 : : {
61 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
62 : : InterfaceBlob *blob;
63 : :
64 : 0 : g_return_val_if_fail (info != NULL, 0);
65 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
66 : :
67 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
68 : :
69 : 0 : return blob->n_prerequisites;
70 : : }
71 : :
72 : : /**
73 : : * gi_interface_info_get_prerequisite:
74 : : * @info: a #GIInterfaceInfo
75 : : * @n: index of prerequisite to get
76 : : *
77 : : * Obtain an interface type’s prerequisite at index @n.
78 : : *
79 : : * Returns: (transfer full): The prerequisite as a [class@GIRepository.BaseInfo].
80 : : * Free the struct by calling [method@GIRepository.BaseInfo.unref] when done.
81 : : * Since: 2.80
82 : : */
83 : : GIBaseInfo *
84 : 0 : gi_interface_info_get_prerequisite (GIInterfaceInfo *info,
85 : : unsigned int n)
86 : : {
87 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
88 : : InterfaceBlob *blob;
89 : :
90 : 0 : g_return_val_if_fail (info != NULL, NULL);
91 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
92 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
93 : :
94 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
95 : :
96 : 0 : return gi_info_from_entry (rinfo->repository,
97 : 0 : rinfo->typelib, blob->prerequisites[n]);
98 : : }
99 : :
100 : :
101 : : /**
102 : : * gi_interface_info_get_n_properties:
103 : : * @info: a #GIInterfaceInfo
104 : : *
105 : : * Obtain the number of properties that this interface type has.
106 : : *
107 : : * Returns: number of properties
108 : : * Since: 2.80
109 : : */
110 : : unsigned int
111 : 0 : gi_interface_info_get_n_properties (GIInterfaceInfo *info)
112 : : {
113 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
114 : : InterfaceBlob *blob;
115 : :
116 : 0 : g_return_val_if_fail (info != NULL, 0);
117 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
118 : :
119 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
120 : :
121 : 0 : return blob->n_properties;
122 : : }
123 : :
124 : : /**
125 : : * gi_interface_info_get_property:
126 : : * @info: a #GIInterfaceInfo
127 : : * @n: index of property to get
128 : : *
129 : : * Obtain an interface type property at index @n.
130 : : *
131 : : * Returns: (transfer full): The [class@GIRepository.PropertyInfo]. Free the
132 : : * struct by calling [method@GIRepository.BaseInfo.unref] when done.
133 : : * Since: 2.80
134 : : */
135 : : GIPropertyInfo *
136 : 0 : gi_interface_info_get_property (GIInterfaceInfo *info,
137 : : unsigned int n)
138 : : {
139 : : size_t offset;
140 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
141 : : Header *header;
142 : : InterfaceBlob *blob;
143 : :
144 : 0 : g_return_val_if_fail (info != NULL, NULL);
145 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
146 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
147 : :
148 : 0 : header = (Header *)rinfo->typelib->data;
149 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
150 : :
151 : 0 : offset = rinfo->offset + header->interface_blob_size
152 : 0 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
153 : 0 : + n * header->property_blob_size;
154 : :
155 : 0 : return (GIPropertyInfo *) gi_base_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
156 : : rinfo->typelib, offset);
157 : : }
158 : :
159 : : /**
160 : : * gi_interface_info_get_n_methods:
161 : : * @info: a #GIInterfaceInfo
162 : : *
163 : : * Obtain the number of methods that this interface type has.
164 : : *
165 : : * Returns: number of methods
166 : : * Since: 2.80
167 : : */
168 : : unsigned int
169 : 0 : gi_interface_info_get_n_methods (GIInterfaceInfo *info)
170 : : {
171 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
172 : : InterfaceBlob *blob;
173 : :
174 : 0 : g_return_val_if_fail (info != NULL, 0);
175 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
176 : :
177 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
178 : :
179 : 0 : return blob->n_methods;
180 : : }
181 : :
182 : : /**
183 : : * gi_interface_info_get_method:
184 : : * @info: a #GIInterfaceInfo
185 : : * @n: index of method to get
186 : : *
187 : : * Obtain an interface type method at index @n.
188 : : *
189 : : * Returns: (transfer full): The [class@GIRepository.FunctionInfo]. Free the
190 : : * struct by calling [method@GIRepository.BaseInfo.unref] when done.
191 : : * Since: 2.80
192 : : */
193 : : GIFunctionInfo *
194 : 10 : gi_interface_info_get_method (GIInterfaceInfo *info,
195 : : unsigned int n)
196 : : {
197 : : size_t offset;
198 : 10 : GIRealInfo *rinfo = (GIRealInfo *)info;
199 : : Header *header;
200 : : InterfaceBlob *blob;
201 : :
202 : 10 : g_return_val_if_fail (info != NULL, NULL);
203 : 10 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
204 : 10 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
205 : :
206 : 10 : header = (Header *)rinfo->typelib->data;
207 : 10 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
208 : :
209 : 10 : offset = rinfo->offset + header->interface_blob_size
210 : 10 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
211 : 10 : + blob->n_properties * header->property_blob_size
212 : 10 : + n * header->function_blob_size;
213 : :
214 : 10 : return (GIFunctionInfo *) gi_base_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
215 : : rinfo->typelib, offset);
216 : : }
217 : :
218 : : /**
219 : : * gi_interface_info_find_method:
220 : : * @info: a #GIInterfaceInfo
221 : : * @name: name of method to obtain
222 : : *
223 : : * Obtain a method of the interface type given a @name.
224 : : *
225 : : * `NULL` will be returned if there’s no method available with that name.
226 : : *
227 : : * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo] or
228 : : * `NULL` if none found. Free the struct by calling
229 : : * [method@GIRepository.BaseInfo.unref] when done.
230 : : * Since: 2.80
231 : : */
232 : : GIFunctionInfo *
233 : 6 : gi_interface_info_find_method (GIInterfaceInfo *info,
234 : : const char *name)
235 : : {
236 : : size_t offset;
237 : 6 : GIRealInfo *rinfo = (GIRealInfo *)info;
238 : 6 : Header *header = (Header *)rinfo->typelib->data;
239 : 6 : InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
240 : :
241 : 6 : offset = rinfo->offset + header->interface_blob_size
242 : 6 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
243 : 6 : + blob->n_properties * header->property_blob_size;
244 : :
245 : 6 : return gi_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
246 : : }
247 : :
248 : : /**
249 : : * gi_interface_info_get_n_signals:
250 : : * @info: a #GIInterfaceInfo
251 : : *
252 : : * Obtain the number of signals that this interface type has.
253 : : *
254 : : * Returns: number of signals
255 : : * Since: 2.80
256 : : */
257 : : unsigned int
258 : 0 : gi_interface_info_get_n_signals (GIInterfaceInfo *info)
259 : : {
260 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
261 : : InterfaceBlob *blob;
262 : :
263 : 0 : g_return_val_if_fail (info != NULL, 0);
264 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
265 : :
266 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
267 : :
268 : 0 : return blob->n_signals;
269 : : }
270 : :
271 : : /**
272 : : * gi_interface_info_get_signal:
273 : : * @info: a #GIInterfaceInfo
274 : : * @n: index of signal to get
275 : : *
276 : : * Obtain an interface type signal at index @n.
277 : : *
278 : : * Returns: (transfer full): The [class@GIRepository.SignalInfo]. Free the
279 : : * struct by calling [method@GIRepository.BaseInfo.unref] when done.
280 : : * Since: 2.80
281 : : */
282 : : GISignalInfo *
283 : 0 : gi_interface_info_get_signal (GIInterfaceInfo *info,
284 : : unsigned int n)
285 : : {
286 : : size_t offset;
287 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
288 : : Header *header;
289 : : InterfaceBlob *blob;
290 : :
291 : 0 : g_return_val_if_fail (info != NULL, NULL);
292 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
293 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
294 : :
295 : 0 : header = (Header *)rinfo->typelib->data;
296 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
297 : :
298 : 0 : offset = rinfo->offset + header->interface_blob_size
299 : 0 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
300 : 0 : + blob->n_properties * header->property_blob_size
301 : 0 : + blob->n_methods * header->function_blob_size
302 : 0 : + n * header->signal_blob_size;
303 : :
304 : 0 : return (GISignalInfo *) gi_base_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
305 : : rinfo->typelib, offset);
306 : : }
307 : :
308 : : /**
309 : : * gi_interface_info_find_signal:
310 : : * @info: a #GIInterfaceInfo
311 : : * @name: name of signal to find
312 : : *
313 : : * Obtain a signal of the interface type given a @name.
314 : : *
315 : : * `NULL` will be returned if there’s no signal available with that name.
316 : : *
317 : : * Returns: (transfer full) (nullable): The [class@GIRepository.SignalInfo] or
318 : : * `NULL` if none found. Free the struct by calling
319 : : * [method@GIRepository.BaseInfo.unref] when done.
320 : : * Since: 2.80
321 : : */
322 : : GISignalInfo *
323 : 0 : gi_interface_info_find_signal (GIInterfaceInfo *info,
324 : : const char *name)
325 : : {
326 : : uint32_t n_signals;
327 : :
328 : 0 : n_signals = gi_interface_info_get_n_signals (info);
329 : 0 : for (uint32_t i = 0; i < n_signals; i++)
330 : : {
331 : 0 : GISignalInfo *siginfo = gi_interface_info_get_signal (info, i);
332 : :
333 : 0 : if (g_strcmp0 (gi_base_info_get_name ((GIBaseInfo *) siginfo), name) != 0)
334 : : {
335 : 0 : gi_base_info_unref ((GIBaseInfo*)siginfo);
336 : 0 : continue;
337 : : }
338 : :
339 : 0 : return siginfo;
340 : : }
341 : 0 : return NULL;
342 : : }
343 : :
344 : : /**
345 : : * gi_interface_info_get_n_vfuncs:
346 : : * @info: a #GIInterfaceInfo
347 : : *
348 : : * Obtain the number of virtual functions that this interface type has.
349 : : *
350 : : * Returns: number of virtual functions
351 : : * Since: 2.80
352 : : */
353 : : unsigned int
354 : 0 : gi_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
355 : : {
356 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
357 : : InterfaceBlob *blob;
358 : :
359 : 0 : g_return_val_if_fail (info != NULL, 0);
360 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
361 : :
362 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
363 : :
364 : 0 : return blob->n_vfuncs;
365 : : }
366 : :
367 : : /**
368 : : * gi_interface_info_get_vfunc:
369 : : * @info: a #GIInterfaceInfo
370 : : * @n: index of virtual function to get
371 : : *
372 : : * Obtain an interface type virtual function at index @n.
373 : : *
374 : : * Returns: (transfer full): the [class@GIRepository.VFuncInfo]. Free the struct
375 : : * by calling [method@GIRepository.BaseInfo.unref] when done.
376 : : * Since: 2.80
377 : : */
378 : : GIVFuncInfo *
379 : 0 : gi_interface_info_get_vfunc (GIInterfaceInfo *info,
380 : : unsigned int n)
381 : : {
382 : : size_t offset;
383 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
384 : : Header *header;
385 : : InterfaceBlob *blob;
386 : :
387 : 0 : g_return_val_if_fail (info != NULL, NULL);
388 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
389 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
390 : :
391 : 0 : header = (Header *)rinfo->typelib->data;
392 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
393 : :
394 : 0 : offset = rinfo->offset + header->interface_blob_size
395 : 0 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
396 : 0 : + blob->n_properties * header->property_blob_size
397 : 0 : + blob->n_methods * header->function_blob_size
398 : 0 : + blob->n_signals * header->signal_blob_size
399 : 0 : + n * header->vfunc_blob_size;
400 : :
401 : 0 : return (GIVFuncInfo *) gi_base_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
402 : : rinfo->typelib, offset);
403 : : }
404 : :
405 : : /**
406 : : * gi_interface_info_find_vfunc:
407 : : * @info: a #GIInterfaceInfo
408 : : * @name: The name of a virtual function to find.
409 : : *
410 : : * Locate a virtual function slot with name @name.
411 : : *
412 : : * See the documentation for [method@GIRepository.ObjectInfo.find_vfunc] for
413 : : * more information on virtuals.
414 : : *
415 : : * Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo], or
416 : : * `NULL` if none found. Free it with [method@GIRepository.BaseInfo.unref]
417 : : * when done.
418 : : * Since: 2.80
419 : : */
420 : : GIVFuncInfo *
421 : 4 : gi_interface_info_find_vfunc (GIInterfaceInfo *info,
422 : : const char *name)
423 : : {
424 : : size_t offset;
425 : 4 : GIRealInfo *rinfo = (GIRealInfo *)info;
426 : : Header *header;
427 : : InterfaceBlob *blob;
428 : :
429 : 4 : g_return_val_if_fail (info != NULL, NULL);
430 : 4 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
431 : :
432 : 4 : header = (Header *)rinfo->typelib->data;
433 : 4 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
434 : :
435 : 4 : offset = rinfo->offset + header->interface_blob_size
436 : 4 : + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2
437 : 4 : + blob->n_properties * header->property_blob_size
438 : 4 : + blob->n_methods * header->function_blob_size
439 : 4 : + blob->n_signals * header->signal_blob_size;
440 : :
441 : 4 : return gi_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name);
442 : : }
443 : :
444 : : /**
445 : : * gi_interface_info_get_n_constants:
446 : : * @info: a #GIInterfaceInfo
447 : : *
448 : : * Obtain the number of constants that this interface type has.
449 : : *
450 : : * Returns: number of constants
451 : : * Since: 2.80
452 : : */
453 : : unsigned int
454 : 0 : gi_interface_info_get_n_constants (GIInterfaceInfo *info)
455 : : {
456 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
457 : : InterfaceBlob *blob;
458 : :
459 : 0 : g_return_val_if_fail (info != NULL, 0);
460 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0);
461 : :
462 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
463 : :
464 : 0 : return blob->n_constants;
465 : : }
466 : :
467 : : /**
468 : : * gi_interface_info_get_constant:
469 : : * @info: a #GIInterfaceInfo
470 : : * @n: index of constant to get
471 : : *
472 : : * Obtain an interface type constant at index @n.
473 : : *
474 : : * Returns: (transfer full): The [class@GIRepository.ConstantInfo]. Free the
475 : : * struct by calling [method@GIRepository.BaseInfo.unref] when done.
476 : : * Since: 2.80
477 : : */
478 : : GIConstantInfo *
479 : 0 : gi_interface_info_get_constant (GIInterfaceInfo *info,
480 : : unsigned int n)
481 : : {
482 : : size_t offset;
483 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
484 : : Header *header;
485 : : InterfaceBlob *blob;
486 : :
487 : 0 : g_return_val_if_fail (info != NULL, NULL);
488 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
489 : 0 : g_return_val_if_fail (n <= G_MAXUINT16, NULL);
490 : :
491 : 0 : header = (Header *)rinfo->typelib->data;
492 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
493 : :
494 : 0 : offset = rinfo->offset + header->interface_blob_size
495 : 0 : + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
496 : 0 : + blob->n_properties * header->property_blob_size
497 : 0 : + blob->n_methods * header->function_blob_size
498 : 0 : + blob->n_signals * header->signal_blob_size
499 : 0 : + blob->n_vfuncs * header->vfunc_blob_size
500 : 0 : + n * header->constant_blob_size;
501 : :
502 : 0 : return (GIConstantInfo *) gi_base_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
503 : : rinfo->typelib, offset);
504 : : }
505 : :
506 : : /**
507 : : * gi_interface_info_get_iface_struct:
508 : : * @info: a #GIInterfaceInfo
509 : : *
510 : : * Returns the layout C structure associated with this `GInterface`.
511 : : *
512 : : * Returns: (transfer full) (nullable): The [class@GIRepository.StructInfo] or
513 : : * `NULL` if unknown. Free it with [method@GIRepository.BaseInfo.unref] when
514 : : * done.
515 : : * Since: 2.80
516 : : */
517 : : GIStructInfo *
518 : 0 : gi_interface_info_get_iface_struct (GIInterfaceInfo *info)
519 : : {
520 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
521 : : InterfaceBlob *blob;
522 : :
523 : 0 : g_return_val_if_fail (info != NULL, NULL);
524 : 0 : g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);
525 : :
526 : 0 : blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
527 : :
528 : 0 : if (blob->gtype_struct)
529 : 0 : return (GIStructInfo *) gi_info_from_entry (rinfo->repository,
530 : 0 : rinfo->typelib, blob->gtype_struct);
531 : : else
532 : 0 : return NULL;
533 : : }
534 : :
535 : : void
536 : 5 : gi_interface_info_class_init (gpointer g_class,
537 : : gpointer class_data)
538 : : {
539 : 5 : GIBaseInfoClass *info_class = g_class;
540 : :
541 : 5 : info_class->info_type = GI_INFO_TYPE_INTERFACE;
542 : 5 : }
|