mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-27 07:56:14 +01:00
25ae968fc2
We are using various indexes types, but not always using the correct sign or size, so let's adapt this to ensure we're consistent with the values we're comparing with.
1189 lines
34 KiB
C
1189 lines
34 KiB
C
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||
* GObject introspection: Object implementation
|
||
*
|
||
* Copyright (C) 2005 Matthias Clasen
|
||
* Copyright (C) 2008,2009 Red Hat, Inc.
|
||
*
|
||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public
|
||
* License as published by the Free Software Foundation; either
|
||
* version 2 of the License, or (at your option) any later version.
|
||
*
|
||
* This library is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
* Lesser General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with this library; if not, write to the
|
||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||
* Boston, MA 02111-1307, USA.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include <glib.h>
|
||
|
||
#include <girepository/girepository.h>
|
||
#include "gibaseinfo-private.h"
|
||
#include "girepository-private.h"
|
||
#include "gitypelib-internal.h"
|
||
#include "giobjectinfo.h"
|
||
|
||
/**
|
||
* GIObjectInfo:
|
||
*
|
||
* `GIObjectInfo` represents a classed type.
|
||
*
|
||
* Classed types in [type@GObject.Type] inherit from
|
||
* [type@GObject.TypeInstance]; the most common type is [class@GObject.Object].
|
||
*
|
||
* A `GIObjectInfo` doesn’t represent a specific instance of a classed type,
|
||
* instead this represent the object type (i.e. the class).
|
||
*
|
||
* A `GIObjectInfo` has methods, fields, properties, signals, interfaces,
|
||
* constants and virtual functions.
|
||
*
|
||
* Since: 2.80
|
||
*/
|
||
|
||
/**
|
||
* gi_object_info_get_field_offset:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of queried field
|
||
*
|
||
* Obtain the offset of the specified field.
|
||
*
|
||
* Returns: field offset, in bytes
|
||
* Since: 2.80
|
||
*/
|
||
static size_t
|
||
gi_object_info_get_field_offset (GIObjectInfo *info,
|
||
size_t n)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header = (Header *)rinfo->typelib->data;
|
||
ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
uint32_t offset;
|
||
FieldBlob *field_blob;
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2;
|
||
|
||
for (size_t i = 0; i < n; i++)
|
||
{
|
||
field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
|
||
offset += header->field_blob_size;
|
||
if (field_blob->has_embedded_type)
|
||
offset += header->callback_blob_size;
|
||
}
|
||
|
||
return offset;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_parent:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the parent of the object type.
|
||
*
|
||
* Returns: (transfer full) (nullable): The `GIObjectInfo`. Free the struct by
|
||
* calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIObjectInfo *
|
||
gi_object_info_get_parent (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->parent)
|
||
return (GIObjectInfo *) gi_info_from_entry (rinfo->repository,
|
||
rinfo->typelib, blob->parent);
|
||
else
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_abstract:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain if the object type is an abstract type, i.e. if it cannot be
|
||
* instantiated.
|
||
*
|
||
* Returns: `TRUE` if the object type is abstract
|
||
* Since: 2.80
|
||
*/
|
||
gboolean
|
||
gi_object_info_get_abstract (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, FALSE);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->abstract != 0;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_final:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Checks whether the object type is a final type, i.e. if it cannot
|
||
* be derived.
|
||
*
|
||
* Returns: `TRUE` if the object type is final
|
||
* Since: 2.80
|
||
*/
|
||
gboolean
|
||
gi_object_info_get_final (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *) info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, FALSE);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
|
||
|
||
blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->final_ != 0;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_fundamental:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain if the object type is of a fundamental type which is not
|
||
* `G_TYPE_OBJECT`.
|
||
*
|
||
* This is mostly for supporting `GstMiniObject`.
|
||
*
|
||
* Returns: `TRUE` if the object type is a fundamental type
|
||
* Since: 2.80
|
||
*/
|
||
gboolean
|
||
gi_object_info_get_fundamental (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, FALSE);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->fundamental != 0;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_type_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the name of the object’s class/type.
|
||
*
|
||
* Returns: name of the object’s type
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_type_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return gi_typelib_get_string (rinfo->typelib, blob->gtype_name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_type_init_function_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the name of the function which, when called, will return the
|
||
* [type@GObject.Type] for this object type.
|
||
*
|
||
* Returns: the type init function name
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_type_init_function_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return gi_typelib_get_string (rinfo->typelib, blob->gtype_init);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_interfaces:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of interfaces that this object type has.
|
||
*
|
||
* Returns: number of interfaces
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_interfaces (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_interfaces;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_interface:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of interface to get
|
||
*
|
||
* Obtain an object type interface at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.InterfaceInfo]. Free the
|
||
* struct by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIInterfaceInfo *
|
||
gi_object_info_get_interface (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return (GIInterfaceInfo *) gi_info_from_entry (rinfo->repository,
|
||
rinfo->typelib, blob->interfaces[n]);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_fields:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of fields that this object type has.
|
||
*
|
||
* Returns: number of fields
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_fields (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_fields;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_field:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of field to get
|
||
*
|
||
* Obtain an object type field at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.FieldInfo]. Free the struct
|
||
* by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIFieldInfo *
|
||
gi_object_info_get_field (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
offset = gi_object_info_get_field_offset(info, n);
|
||
|
||
return (GIFieldInfo *) gi_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_properties:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of properties that this object type has.
|
||
*
|
||
* Returns: number of properties
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_properties (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
return blob->n_properties;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_property:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of property to get
|
||
*
|
||
* Obtain an object type property at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.PropertyInfo]. Free the
|
||
* struct by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIPropertyInfo *
|
||
gi_object_info_get_property (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ n * header->property_blob_size;
|
||
|
||
return (GIPropertyInfo *) gi_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
|
||
rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_methods:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of methods that this object type has.
|
||
*
|
||
* Returns: number of methods
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_methods (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_methods;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_method:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of method to get
|
||
*
|
||
* Obtain an object type method at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.FunctionInfo]. Free the
|
||
* struct by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIFunctionInfo *
|
||
gi_object_info_get_method (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size
|
||
+ n * header->function_blob_size;
|
||
|
||
return (GIFunctionInfo *) gi_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
|
||
rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_find_method:
|
||
* @info: a #GIObjectInfo
|
||
* @name: name of method to obtain
|
||
*
|
||
* Obtain a method of the object type given a @name.
|
||
*
|
||
* `NULL` will be returned if there’s no method available with that name.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
|
||
* or `NULL` if no method could be found. Free the struct by calling
|
||
* [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIFunctionInfo *
|
||
gi_object_info_find_method (GIObjectInfo *info,
|
||
const char *name)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size +
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size;
|
||
|
||
return gi_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_find_method_using_interfaces:
|
||
* @info: a #GIObjectInfo
|
||
* @name: name of method to obtain
|
||
* @implementor: (out) (transfer full) (optional) (nullable): The implementor of
|
||
* the interface, or `NULL` to ignore. If no method is found, this will return
|
||
* `NULL`.
|
||
*
|
||
* Obtain a method of the object given a @name, searching both the
|
||
* object @info and any interfaces it implements.
|
||
*
|
||
* `NULL` will be returned if there’s no method available with that name.
|
||
*
|
||
* Note that this function does *not* search parent classes; you will have
|
||
* to chain up if that’s desired.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
|
||
* or `NULL` if none was found. Free the struct by calling
|
||
* [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIFunctionInfo *
|
||
gi_object_info_find_method_using_interfaces (GIObjectInfo *info,
|
||
const char *name,
|
||
GIObjectInfo **implementor)
|
||
{
|
||
GIFunctionInfo *result = NULL;
|
||
GIObjectInfo *implementor_result = NULL;
|
||
|
||
result = gi_object_info_find_method (info, name);
|
||
if (result)
|
||
implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
|
||
|
||
if (result == NULL)
|
||
{
|
||
int n_interfaces;
|
||
int i;
|
||
|
||
n_interfaces = gi_object_info_get_n_interfaces (info);
|
||
for (i = 0; i < n_interfaces; ++i)
|
||
{
|
||
GIInterfaceInfo *iface_info;
|
||
|
||
iface_info = gi_object_info_get_interface (info, i);
|
||
|
||
result = gi_interface_info_find_method (iface_info, name);
|
||
|
||
if (result != NULL)
|
||
{
|
||
implementor_result = (GIObjectInfo *) iface_info;
|
||
break;
|
||
}
|
||
gi_base_info_unref ((GIBaseInfo*) iface_info);
|
||
}
|
||
}
|
||
if (implementor)
|
||
*implementor = implementor_result;
|
||
else if (implementor_result != NULL)
|
||
gi_base_info_unref ((GIBaseInfo*) implementor_result);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_signals:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of signals that this object type has.
|
||
*
|
||
* Returns: number of signals
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_signals (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_signals;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_signal:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of signal to get
|
||
*
|
||
* Obtain an object type signal at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.SignalInfo]. Free the
|
||
* struct by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GISignalInfo *
|
||
gi_object_info_get_signal (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size
|
||
+ blob->n_methods * header->function_blob_size
|
||
+ n * header->signal_blob_size;
|
||
|
||
return (GISignalInfo *) gi_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
|
||
rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_find_signal:
|
||
* @info: a #GIObjectInfo
|
||
* @name: name of signal
|
||
*
|
||
* Obtain a signal of the object type given a @name.
|
||
*
|
||
* `NULL` will be returned if there’s no signal available with that name.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.SignalInfo],
|
||
* or `NULL` if no signal could be found. Free the struct by calling
|
||
* [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GISignalInfo *
|
||
gi_object_info_find_signal (GIObjectInfo *info,
|
||
const char *name)
|
||
{
|
||
size_t n_signals;
|
||
|
||
n_signals = gi_object_info_get_n_signals (info);
|
||
for (size_t i = 0; i < n_signals; i++)
|
||
{
|
||
GISignalInfo *siginfo = gi_object_info_get_signal (info, i);
|
||
|
||
if (g_strcmp0 (gi_base_info_get_name ((GIBaseInfo *) siginfo), name) != 0)
|
||
{
|
||
gi_base_info_unref ((GIBaseInfo*)siginfo);
|
||
continue;
|
||
}
|
||
|
||
return siginfo;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
|
||
/**
|
||
* gi_object_info_get_n_vfuncs:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of virtual functions that this object type has.
|
||
*
|
||
* Returns: number of virtual functions
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_vfuncs (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_vfuncs;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_vfunc:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of virtual function to get
|
||
*
|
||
* Obtain an object type virtual function at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.VFuncInfo]. Free the struct
|
||
* by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIVFuncInfo *
|
||
gi_object_info_get_vfunc (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size
|
||
+ blob->n_methods * header->function_blob_size
|
||
+ blob->n_signals * header->signal_blob_size
|
||
+ n * header->vfunc_blob_size;
|
||
|
||
return (GIVFuncInfo *) gi_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
|
||
rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_find_vfunc:
|
||
* @info: a #GIObjectInfo
|
||
* @name: the name of a virtual function to find.
|
||
*
|
||
* Locate a virtual function slot with name @name.
|
||
*
|
||
* Note that the namespace for virtuals is distinct from that of methods; there
|
||
* may or may not be a concrete method associated for a virtual. If there is
|
||
* one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
|
||
* otherwise that method will return `NULL`.
|
||
*
|
||
* See the documentation for [method@GIRepository.VFuncInfo.get_invoker] for
|
||
* more information on invoking virtuals.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo], or
|
||
* `NULL` if none is found. Free it with [method@GIRepository.BaseInfo.unref]
|
||
* when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIVFuncInfo *
|
||
gi_object_info_find_vfunc (GIObjectInfo *info,
|
||
const char *name)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size
|
||
+ blob->n_methods * header->function_blob_size
|
||
+ blob->n_signals * header->signal_blob_size;
|
||
|
||
return gi_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_find_vfunc_using_interfaces:
|
||
* @info: a #GIObjectInfo
|
||
* @name: name of vfunc to obtain
|
||
* @implementor: (out) (transfer full) (optional) (nullable): The implementor of
|
||
* the interface, or `NULL` to ignore. If no vfunc is found, this will return
|
||
* `NULL`.
|
||
*
|
||
* Locate a virtual function slot with name @name, searching both the object
|
||
* @info and any interfaces it implements.
|
||
*
|
||
* `NULL` will be returned if there’s no vfunc available with that name.
|
||
*
|
||
* Note that the namespace for virtuals is distinct from that of methods; there
|
||
* may or may not be a concrete method associated for a virtual. If there is
|
||
* one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
|
||
* otherwise that method will return `NULL`.
|
||
*
|
||
* Note that this function does *not* search parent classes; you will have
|
||
* to chain up if that’s desired.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo],
|
||
* or `NULL` if none was found. Free the struct by calling
|
||
* [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIVFuncInfo *
|
||
gi_object_info_find_vfunc_using_interfaces (GIObjectInfo *info,
|
||
const char *name,
|
||
GIObjectInfo **implementor)
|
||
{
|
||
GIVFuncInfo *result = NULL;
|
||
GIObjectInfo *implementor_result = NULL;
|
||
|
||
result = gi_object_info_find_vfunc (info, name);
|
||
if (result)
|
||
implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
|
||
|
||
if (result == NULL)
|
||
{
|
||
int n_interfaces;
|
||
int i;
|
||
|
||
n_interfaces = gi_object_info_get_n_interfaces (info);
|
||
for (i = 0; i < n_interfaces; ++i)
|
||
{
|
||
GIInterfaceInfo *iface_info;
|
||
|
||
iface_info = gi_object_info_get_interface (info, i);
|
||
|
||
result = gi_interface_info_find_vfunc (iface_info, name);
|
||
|
||
if (result != NULL)
|
||
{
|
||
implementor_result = (GIObjectInfo *) iface_info;
|
||
break;
|
||
}
|
||
gi_base_info_unref ((GIBaseInfo*) iface_info);
|
||
}
|
||
}
|
||
if (implementor)
|
||
*implementor = implementor_result;
|
||
else if (implementor_result != NULL)
|
||
gi_base_info_unref ((GIBaseInfo*) implementor_result);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_n_constants:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the number of constants that this object type has.
|
||
*
|
||
* Returns: number of constants
|
||
* Since: 2.80
|
||
*/
|
||
unsigned int
|
||
gi_object_info_get_n_constants (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, 0);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
return blob->n_constants;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_constant:
|
||
* @info: a #GIObjectInfo
|
||
* @n: index of constant to get
|
||
*
|
||
* Obtain an object type constant at index @n.
|
||
*
|
||
* Returns: (transfer full): The [class@GIRepository.ConstantInfo]. Free the
|
||
* struct by calling [method@GIRepository.BaseInfo.unref] when done.
|
||
* Since: 2.80
|
||
*/
|
||
GIConstantInfo *
|
||
gi_object_info_get_constant (GIObjectInfo *info,
|
||
unsigned int n)
|
||
{
|
||
size_t offset;
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
Header *header;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
g_return_val_if_fail (n <= G_MAXUINT16, NULL);
|
||
|
||
header = (Header *)rinfo->typelib->data;
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
offset = rinfo->offset + header->object_blob_size
|
||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||
+ blob->n_fields * header->field_blob_size
|
||
+ blob->n_field_callbacks * header->callback_blob_size
|
||
+ blob->n_properties * header->property_blob_size
|
||
+ blob->n_methods * header->function_blob_size
|
||
+ blob->n_signals * header->signal_blob_size
|
||
+ blob->n_vfuncs * header->vfunc_blob_size
|
||
+ n * header->constant_blob_size;
|
||
|
||
return (GIConstantInfo *) gi_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
|
||
rinfo->typelib, offset);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_class_struct:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Every [class@GObject.Object] has two structures; an instance structure and a
|
||
* class structure. This function returns the metadata for the class structure.
|
||
*
|
||
* Returns: (transfer full) (nullable): The [class@GIRepository.StructInfo] or
|
||
* `NULL` if it’s unknown. Free with [method@GIRepository.BaseInfo.unref] when
|
||
* done.
|
||
* Since: 2.80
|
||
*/
|
||
GIStructInfo *
|
||
gi_object_info_get_class_struct (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->gtype_struct)
|
||
return (GIStructInfo *) gi_info_from_entry (rinfo->repository,
|
||
rinfo->typelib, blob->gtype_struct);
|
||
else
|
||
return NULL;
|
||
}
|
||
|
||
typedef const char* (*SymbolGetter) (GIObjectInfo *info);
|
||
|
||
static void *
|
||
_get_func(GIObjectInfo *info,
|
||
SymbolGetter getter)
|
||
{
|
||
const char* symbol;
|
||
GSList *parents = NULL, *l;
|
||
GIObjectInfo *parent_info;
|
||
void *func = NULL;
|
||
|
||
parent_info = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo *) info);
|
||
while (parent_info != NULL)
|
||
{
|
||
parents = g_slist_prepend (parents, parent_info);
|
||
parent_info = gi_object_info_get_parent (parent_info);
|
||
}
|
||
|
||
for (l = parents; l; l = l->next)
|
||
{
|
||
parent_info = l->data;
|
||
symbol = getter (parent_info);
|
||
if (symbol == NULL)
|
||
continue;
|
||
|
||
gi_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (gpointer*) &func);
|
||
if (func)
|
||
break;
|
||
}
|
||
|
||
g_slist_free_full (parents, (GDestroyNotify) gi_base_info_unref);
|
||
return func;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_ref_function_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the symbol name of the function that should be called to ref this
|
||
* object type.
|
||
*
|
||
* It’s mainly used for fundamental types. The type signature for
|
||
* the symbol is [type@GIRepository.ObjectInfoRefFunction]. To fetch the
|
||
* function pointer see
|
||
* [method@GIRepository.ObjectInfo.get_ref_function_pointer].
|
||
*
|
||
* Returns: (nullable): the symbol, or `NULL` if the object type has no ref
|
||
* function
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_ref_function_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->ref_func)
|
||
return gi_typelib_get_string (rinfo->typelib, blob->ref_func);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_ref_function_pointer: (skip)
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain a pointer to a function which can be used to
|
||
* increase the reference count an instance of this object type.
|
||
*
|
||
* This takes derivation into account and will reversely traverse
|
||
* the base classes of this type, starting at the top type.
|
||
*
|
||
* Returns: (nullable): the function pointer, or `NULL` if the object type has
|
||
* no ref function
|
||
* Since: 2.80
|
||
*/
|
||
GIObjectInfoRefFunction
|
||
gi_object_info_get_ref_function_pointer (GIObjectInfo *info)
|
||
{
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_ref_function_name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_unref_function_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the symbol name of the function that should be called to unref this
|
||
* object type.
|
||
*
|
||
* It’s mainly used for fundamental types. The type signature for the symbol is
|
||
* [type@GIRepository.ObjectInfoUnrefFunction]. To fetch the function pointer
|
||
* see [method@GIRepository.ObjectInfo.get_unref_function_pointer].
|
||
*
|
||
* Returns: (nullable): the symbol, or `NULL` if the object type has no unref
|
||
* function
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_unref_function_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->unref_func)
|
||
return gi_typelib_get_string (rinfo->typelib, blob->unref_func);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_unref_function_pointer: (skip)
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain a pointer to a function which can be used to
|
||
* decrease the reference count an instance of this object type.
|
||
*
|
||
* This takes derivation into account and will reversely traverse
|
||
* the base classes of this type, starting at the top type.
|
||
*
|
||
* Returns: (nullable): the function pointer, or `NULL` if the object type has
|
||
* no unref function
|
||
* Since: 2.80
|
||
*/
|
||
GIObjectInfoUnrefFunction
|
||
gi_object_info_get_unref_function_pointer (GIObjectInfo *info)
|
||
{
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_unref_function_name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_set_value_function_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the symbol name of the function that should be called to set a
|
||
* [type@GObject.Value], given an object instance pointer of this object type.
|
||
*
|
||
* It’s mainly used for fundamental types. The type signature for the symbol
|
||
* is [type@GIRepository.ObjectInfoSetValueFunction]. To fetch the function
|
||
* pointer see [method@GIRepository.ObjectInfo.get_set_value_function_pointer].
|
||
*
|
||
* Returns: (nullable): the symbol, or `NULL` if the object type has no
|
||
* set-value function
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_set_value_function_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->set_value_func)
|
||
return gi_typelib_get_string (rinfo->typelib, blob->set_value_func);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_set_value_function_pointer: (skip)
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain a pointer to a function which can be used to set a
|
||
* [type@GObject.Value], given an instance of this object type.
|
||
*
|
||
* This takes derivation into account and will reversely traverse
|
||
* the base classes of this type, starting at the top type.
|
||
*
|
||
* Returns: (nullable): the function pointer, or `NULL` if the object type has
|
||
* no set-value function
|
||
* Since: 2.80
|
||
*/
|
||
GIObjectInfoSetValueFunction
|
||
gi_object_info_get_set_value_function_pointer (GIObjectInfo *info)
|
||
{
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_set_value_function_name);
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_get_value_function_name:
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain the symbol name of the function that should be called to convert
|
||
* an object instance pointer of this object type to a [type@GObject.Value].
|
||
*
|
||
* It’s mainly used for fundamental types. The type signature for the symbol
|
||
* is [type@GIRepository.ObjectInfoGetValueFunction]. To fetch the function
|
||
* pointer see [method@GIRepository.ObjectInfo.get_get_value_function_pointer].
|
||
*
|
||
* Returns: (nullable): the symbol, or `NULL` if the object type has no
|
||
* get-value function
|
||
* Since: 2.80
|
||
*/
|
||
const char *
|
||
gi_object_info_get_get_value_function_name (GIObjectInfo *info)
|
||
{
|
||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||
ObjectBlob *blob;
|
||
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||
|
||
if (blob->get_value_func)
|
||
return gi_typelib_get_string (rinfo->typelib, blob->get_value_func);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* gi_object_info_get_get_value_function_pointer: (skip)
|
||
* @info: a #GIObjectInfo
|
||
*
|
||
* Obtain a pointer to a function which can be used to extract an instance of
|
||
* this object type out of a [type@GObject.Value].
|
||
*
|
||
* This takes derivation into account and will reversely traverse
|
||
* the base classes of this type, starting at the top type.
|
||
*
|
||
* Returns: (nullable): the function pointer, or `NULL` if the object type has
|
||
* no get-value function
|
||
* Since: 2.80
|
||
*/
|
||
GIObjectInfoGetValueFunction
|
||
gi_object_info_get_get_value_function_pointer (GIObjectInfo *info)
|
||
{
|
||
g_return_val_if_fail (info != NULL, NULL);
|
||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||
|
||
return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_get_value_function_name);
|
||
}
|
||
|
||
void
|
||
gi_object_info_class_init (gpointer g_class,
|
||
gpointer class_data)
|
||
{
|
||
GIBaseInfoClass *info_class = g_class;
|
||
|
||
info_class->info_type = GI_INFO_TYPE_OBJECT;
|
||
}
|