(root)/
glib-2.79.0/
girepository/
giobjectinfo.c
       1  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2   * GObject introspection: Object 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 "giobjectinfo.h"
      34  
      35  /**
      36   * GIObjectInfo:
      37   *
      38   * `GIObjectInfo` represents a classed type.
      39   *
      40   * Classed types in [type@GObject.Type] inherit from
      41   * [type@GObject.TypeInstance]; the most common type is [class@GObject.Object].
      42   *
      43   * A `GIObjectInfo` doesn’t represent a specific instance of a classed type,
      44   * instead this represent the object type (i.e. the class).
      45   *
      46   * A `GIObjectInfo` has methods, fields, properties, signals, interfaces,
      47   * constants and virtual functions.
      48   *
      49   * Since: 2.80
      50   */
      51  
      52  /**
      53   * gi_object_info_get_field_offset:
      54   * @info: a #GIObjectInfo
      55   * @n: index of queried field
      56   *
      57   * Obtain the offset of the specified field.
      58   *
      59   * Returns: field offset, in bytes
      60   * Since: 2.80
      61   */
      62  static gint32
      63  gi_object_info_get_field_offset (GIObjectInfo *info,
      64                                   guint         n)
      65  {
      66    GIRealInfo *rinfo = (GIRealInfo *)info;
      67    Header *header = (Header *)rinfo->typelib->data;
      68    ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
      69    guint32 offset;
      70    FieldBlob *field_blob;
      71  
      72    offset = rinfo->offset + header->object_blob_size
      73      + (blob->n_interfaces + blob->n_interfaces % 2) * 2;
      74  
      75    for (guint i = 0; i < n; i++)
      76      {
      77        field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
      78        offset += header->field_blob_size;
      79        if (field_blob->has_embedded_type)
      80          offset += header->callback_blob_size;
      81      }
      82  
      83    return offset;
      84  }
      85  
      86  /**
      87   * gi_object_info_get_parent:
      88   * @info: a #GIObjectInfo
      89   *
      90   * Obtain the parent of the object type.
      91   *
      92   * Returns: (transfer full) (nullable): The `GIObjectInfo`. Free the struct by
      93   *   calling [method@GIRepository.BaseInfo.unref] when done.
      94   * Since: 2.80
      95   */
      96  GIObjectInfo *
      97  gi_object_info_get_parent (GIObjectInfo *info)
      98  {
      99    GIRealInfo *rinfo = (GIRealInfo *)info;
     100    ObjectBlob *blob;
     101  
     102    g_return_val_if_fail (info != NULL, NULL);
     103    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     104  
     105    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     106  
     107    if (blob->parent)
     108      return (GIObjectInfo *) gi_info_from_entry (rinfo->repository,
     109                                                  rinfo->typelib, blob->parent);
     110    else
     111      return NULL;
     112  }
     113  
     114  /**
     115   * gi_object_info_get_abstract:
     116   * @info: a #GIObjectInfo
     117   *
     118   * Obtain if the object type is an abstract type, i.e. if it cannot be
     119   * instantiated.
     120   *
     121   * Returns: `TRUE` if the object type is abstract
     122   * Since: 2.80
     123   */
     124  gboolean
     125  gi_object_info_get_abstract (GIObjectInfo *info)
     126  {
     127    GIRealInfo *rinfo = (GIRealInfo *)info;
     128    ObjectBlob *blob;
     129  
     130    g_return_val_if_fail (info != NULL, FALSE);
     131    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
     132  
     133    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     134  
     135    return blob->abstract != 0;
     136  }
     137  
     138  /**
     139   * gi_object_info_get_final:
     140   * @info: a #GIObjectInfo
     141   *
     142   * Checks whether the object type is a final type, i.e. if it cannot
     143   * be derived.
     144   *
     145   * Returns: `TRUE` if the object type is final
     146   * Since: 2.80
     147   */
     148  gboolean
     149  gi_object_info_get_final (GIObjectInfo *info)
     150  {
     151    GIRealInfo *rinfo = (GIRealInfo *) info;
     152    ObjectBlob *blob;
     153  
     154    g_return_val_if_fail (info != NULL, FALSE);
     155    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
     156  
     157    blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset];
     158  
     159    return blob->final_ != 0;
     160  }
     161  
     162  /**
     163   * gi_object_info_get_fundamental:
     164   * @info: a #GIObjectInfo
     165   *
     166   * Obtain if the object type is of a fundamental type which is not
     167   * `G_TYPE_OBJECT`.
     168   *
     169   * This is mostly for supporting `GstMiniObject`.
     170   *
     171   * Returns: `TRUE` if the object type is a fundamental type
     172   * Since: 2.80
     173   */
     174  gboolean
     175  gi_object_info_get_fundamental (GIObjectInfo *info)
     176  {
     177    GIRealInfo *rinfo = (GIRealInfo *)info;
     178    ObjectBlob *blob;
     179  
     180    g_return_val_if_fail (info != NULL, FALSE);
     181    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
     182  
     183    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     184  
     185    return blob->fundamental != 0;
     186  }
     187  
     188  /**
     189   * gi_object_info_get_type_name:
     190   * @info: a #GIObjectInfo
     191   *
     192   * Obtain the name of the object’s class/type.
     193   *
     194   * Returns: name of the object’s type
     195   * Since: 2.80
     196   */
     197  const gchar *
     198  gi_object_info_get_type_name (GIObjectInfo *info)
     199  {
     200    GIRealInfo *rinfo = (GIRealInfo *)info;
     201    ObjectBlob *blob;
     202  
     203    g_return_val_if_fail (info != NULL, NULL);
     204    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     205  
     206    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     207  
     208    return gi_typelib_get_string (rinfo->typelib, blob->gtype_name);
     209  }
     210  
     211  /**
     212   * gi_object_info_get_type_init_function_name:
     213   * @info: a #GIObjectInfo
     214   *
     215   * Obtain the name of the function which, when called, will return the
     216   * [type@GObject.Type] for this object type.
     217   *
     218   * Returns: the type init function name
     219   * Since: 2.80
     220   */
     221  const gchar *
     222  gi_object_info_get_type_init_function_name (GIObjectInfo *info)
     223  {
     224    GIRealInfo *rinfo = (GIRealInfo *)info;
     225    ObjectBlob *blob;
     226  
     227    g_return_val_if_fail (info != NULL, NULL);
     228    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     229  
     230    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     231  
     232    return gi_typelib_get_string (rinfo->typelib, blob->gtype_init);
     233  }
     234  
     235  /**
     236   * gi_object_info_get_n_interfaces:
     237   * @info: a #GIObjectInfo
     238   *
     239   * Obtain the number of interfaces that this object type has.
     240   *
     241   * Returns: number of interfaces
     242   * Since: 2.80
     243   */
     244  guint
     245  gi_object_info_get_n_interfaces (GIObjectInfo *info)
     246  {
     247    GIRealInfo *rinfo = (GIRealInfo *)info;
     248    ObjectBlob *blob;
     249  
     250    g_return_val_if_fail (info != NULL, 0);
     251    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     252  
     253    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     254  
     255    return blob->n_interfaces;
     256  }
     257  
     258  /**
     259   * gi_object_info_get_interface:
     260   * @info: a #GIObjectInfo
     261   * @n: index of interface to get
     262   *
     263   * Obtain an object type interface at index @n.
     264   *
     265   * Returns: (transfer full): The [class@GIRepository.InterfaceInfo]. Free the
     266   *   struct by calling [method@GIRepository.BaseInfo.unref] when done.
     267   * Since: 2.80
     268   */
     269  GIInterfaceInfo *
     270  gi_object_info_get_interface (GIObjectInfo *info,
     271                                guint         n)
     272  {
     273    GIRealInfo *rinfo = (GIRealInfo *)info;
     274    ObjectBlob *blob;
     275  
     276    g_return_val_if_fail (info != NULL, NULL);
     277    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     278  
     279    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     280  
     281    return (GIInterfaceInfo *) gi_info_from_entry (rinfo->repository,
     282                                                   rinfo->typelib, blob->interfaces[n]);
     283  }
     284  
     285  /**
     286   * gi_object_info_get_n_fields:
     287   * @info: a #GIObjectInfo
     288   *
     289   * Obtain the number of fields that this object type has.
     290   *
     291   * Returns: number of fields
     292   * Since: 2.80
     293   */
     294  guint
     295  gi_object_info_get_n_fields (GIObjectInfo *info)
     296  {
     297    GIRealInfo *rinfo = (GIRealInfo *)info;
     298    ObjectBlob *blob;
     299  
     300    g_return_val_if_fail (info != NULL, 0);
     301    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     302  
     303    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     304  
     305    return blob->n_fields;
     306  }
     307  
     308  /**
     309   * gi_object_info_get_field:
     310   * @info: a #GIObjectInfo
     311   * @n: index of field to get
     312   *
     313   * Obtain an object type field at index @n.
     314   *
     315   * Returns: (transfer full): The [class@GIRepository.FieldInfo]. Free the struct
     316   *   by calling [method@GIRepository.BaseInfo.unref] when done.
     317   * Since: 2.80
     318   */
     319  GIFieldInfo *
     320  gi_object_info_get_field (GIObjectInfo *info,
     321                            guint         n)
     322  {
     323    gint offset;
     324    GIRealInfo *rinfo = (GIRealInfo *)info;
     325  
     326    g_return_val_if_fail (info != NULL, NULL);
     327    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     328  
     329    offset = gi_object_info_get_field_offset(info, n);
     330  
     331    return (GIFieldInfo *) gi_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
     332  }
     333  
     334  /**
     335   * gi_object_info_get_n_properties:
     336   * @info: a #GIObjectInfo
     337   *
     338   * Obtain the number of properties that this object type has.
     339   *
     340   * Returns: number of properties
     341   * Since: 2.80
     342   */
     343  guint
     344  gi_object_info_get_n_properties (GIObjectInfo *info)
     345  {
     346    GIRealInfo *rinfo = (GIRealInfo *)info;
     347    ObjectBlob *blob;
     348  
     349    g_return_val_if_fail (info != NULL, 0);
     350    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     351  
     352    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     353    return blob->n_properties;
     354  }
     355  
     356  /**
     357   * gi_object_info_get_property:
     358   * @info: a #GIObjectInfo
     359   * @n: index of property to get
     360   *
     361   * Obtain an object type property at index @n.
     362   *
     363   * Returns: (transfer full): The [class@GIRepository.PropertyInfo]. Free the
     364   *   struct by calling [method@GIRepository.BaseInfo.unref] when done.
     365   * Since: 2.80
     366   */
     367  GIPropertyInfo *
     368  gi_object_info_get_property (GIObjectInfo *info,
     369                               guint         n)
     370  {
     371    gint offset;
     372    GIRealInfo *rinfo = (GIRealInfo *)info;
     373    Header *header;
     374    ObjectBlob *blob;
     375  
     376    g_return_val_if_fail (info != NULL, NULL);
     377    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     378  
     379    header = (Header *)rinfo->typelib->data;
     380    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     381  
     382    offset = rinfo->offset + header->object_blob_size
     383      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     384      + blob->n_fields * header->field_blob_size
     385      + blob->n_field_callbacks * header->callback_blob_size
     386      + n * header->property_blob_size;
     387  
     388    return (GIPropertyInfo *) gi_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
     389                                           rinfo->typelib, offset);
     390  }
     391  
     392  /**
     393   * gi_object_info_get_n_methods:
     394   * @info: a #GIObjectInfo
     395   *
     396   * Obtain the number of methods that this object type has.
     397   *
     398   * Returns: number of methods
     399   * Since: 2.80
     400   */
     401  guint
     402  gi_object_info_get_n_methods (GIObjectInfo *info)
     403  {
     404    GIRealInfo *rinfo = (GIRealInfo *)info;
     405    ObjectBlob *blob;
     406  
     407    g_return_val_if_fail (info != NULL, 0);
     408    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     409  
     410    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     411  
     412    return blob->n_methods;
     413  }
     414  
     415  /**
     416   * gi_object_info_get_method:
     417   * @info: a #GIObjectInfo
     418   * @n: index of method to get
     419   *
     420   * Obtain an object type method at index @n.
     421   *
     422   * Returns: (transfer full): The [class@GIRepository.FunctionInfo]. Free the
     423   *   struct by calling [method@GIRepository.BaseInfo.unref] when done.
     424   * Since: 2.80
     425   */
     426  GIFunctionInfo *
     427  gi_object_info_get_method (GIObjectInfo *info,
     428                             guint         n)
     429  {
     430    gint offset;
     431    GIRealInfo *rinfo = (GIRealInfo *)info;
     432    Header *header;
     433    ObjectBlob *blob;
     434  
     435    g_return_val_if_fail (info != NULL, NULL);
     436    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     437  
     438    header = (Header *)rinfo->typelib->data;
     439    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     440  
     441  
     442    offset = rinfo->offset + header->object_blob_size
     443      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     444      + blob->n_fields * header->field_blob_size
     445      + blob->n_field_callbacks * header->callback_blob_size
     446      + blob->n_properties * header->property_blob_size
     447      + n * header->function_blob_size;
     448  
     449      return (GIFunctionInfo *) gi_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
     450                                             rinfo->typelib, offset);
     451  }
     452  
     453  /**
     454   * gi_object_info_find_method:
     455   * @info: a #GIObjectInfo
     456   * @name: name of method to obtain
     457   *
     458   * Obtain a method of the object type given a @name.
     459   *
     460   * `NULL` will be returned if there’s no method available with that name.
     461   *
     462   * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
     463   *   or `NULL` if no method could be found. Free the struct by calling
     464   *   [method@GIRepository.BaseInfo.unref] when done.
     465   * Since: 2.80
     466   */
     467  GIFunctionInfo *
     468  gi_object_info_find_method (GIObjectInfo *info,
     469                              const gchar  *name)
     470  {
     471    gint offset;
     472    GIRealInfo *rinfo = (GIRealInfo *)info;
     473    Header *header;
     474    ObjectBlob *blob;
     475  
     476    g_return_val_if_fail (info != NULL, 0);
     477    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     478  
     479    header = (Header *)rinfo->typelib->data;
     480    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     481  
     482    offset = rinfo->offset + header->object_blob_size
     483      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     484      + blob->n_fields * header->field_blob_size +
     485      + blob->n_field_callbacks * header->callback_blob_size
     486      + blob->n_properties * header->property_blob_size;
     487  
     488    return gi_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
     489  }
     490  
     491  /**
     492   * gi_object_info_find_method_using_interfaces:
     493   * @info: a #GIObjectInfo
     494   * @name: name of method to obtain
     495   * @implementor: (out) (transfer full) (optional) (nullable): The implementor of
     496   *   the interface, or `NULL` to ignore. If no method is found, this will return
     497   *   `NULL`.
     498   *
     499   * Obtain a method of the object given a @name, searching both the
     500   * object @info and any interfaces it implements.
     501   *
     502   * `NULL` will be returned if there’s no method available with that name.
     503   *
     504   * Note that this function does *not* search parent classes; you will have
     505   * to chain up if that’s desired.
     506   *
     507   * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
     508   *   or `NULL` if none was found. Free the struct by calling
     509   *   [method@GIRepository.BaseInfo.unref] when done.
     510   * Since: 2.80
     511   */
     512  GIFunctionInfo *
     513  gi_object_info_find_method_using_interfaces (GIObjectInfo  *info,
     514                                               const gchar   *name,
     515                                               GIObjectInfo **implementor)
     516  {
     517    GIFunctionInfo *result = NULL;
     518    GIObjectInfo *implementor_result = NULL;
     519  
     520    result = gi_object_info_find_method (info, name);
     521    if (result)
     522      implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
     523  
     524    if (result == NULL)
     525      {
     526        int n_interfaces;
     527        int i;
     528  
     529        n_interfaces = gi_object_info_get_n_interfaces (info);
     530        for (i = 0; i < n_interfaces; ++i)
     531  	{
     532  	  GIInterfaceInfo *iface_info;
     533  
     534  	  iface_info = gi_object_info_get_interface (info, i);
     535  
     536  	  result = gi_interface_info_find_method (iface_info, name);
     537  
     538  	  if (result != NULL)
     539  	    {
     540  	      implementor_result = (GIObjectInfo *) iface_info;
     541  	      break;
     542  	    }
     543  	  gi_base_info_unref ((GIBaseInfo*) iface_info);
     544  	}
     545      }
     546    if (implementor)
     547      *implementor = implementor_result;
     548    else if (implementor_result != NULL)
     549      gi_base_info_unref ((GIBaseInfo*) implementor_result);
     550    return result;
     551  }
     552  
     553  /**
     554   * gi_object_info_get_n_signals:
     555   * @info: a #GIObjectInfo
     556   *
     557   * Obtain the number of signals that this object type has.
     558   *
     559   * Returns: number of signals
     560   * Since: 2.80
     561   */
     562  guint
     563  gi_object_info_get_n_signals (GIObjectInfo *info)
     564  {
     565    GIRealInfo *rinfo = (GIRealInfo *)info;
     566    ObjectBlob *blob;
     567  
     568    g_return_val_if_fail (info != NULL, 0);
     569    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     570  
     571    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     572  
     573    return blob->n_signals;
     574  }
     575  
     576  /**
     577   * gi_object_info_get_signal:
     578   * @info: a #GIObjectInfo
     579   * @n: index of signal to get
     580   *
     581   * Obtain an object type signal at index @n.
     582   *
     583   * Returns: (transfer full): The [class@GIRepository.SignalInfo]. Free the
     584   *   struct by calling [method@GIRepository.BaseInfo.unref] when done.
     585   * Since: 2.80
     586   */
     587  GISignalInfo *
     588  gi_object_info_get_signal (GIObjectInfo *info,
     589                             guint         n)
     590  {
     591    gint offset;
     592    GIRealInfo *rinfo = (GIRealInfo *)info;
     593    Header *header;
     594    ObjectBlob *blob;
     595  
     596    g_return_val_if_fail (info != NULL, NULL);
     597    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     598  
     599    header = (Header *)rinfo->typelib->data;
     600    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     601  
     602    offset = rinfo->offset + header->object_blob_size
     603      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     604      + blob->n_fields * header->field_blob_size
     605      + blob->n_field_callbacks * header->callback_blob_size
     606      + blob->n_properties * header->property_blob_size
     607      + blob->n_methods * header->function_blob_size
     608      + n * header->signal_blob_size;
     609  
     610    return (GISignalInfo *) gi_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
     611                                         rinfo->typelib, offset);
     612  }
     613  
     614  /**
     615   * gi_object_info_find_signal:
     616   * @info: a #GIObjectInfo
     617   * @name: name of signal
     618   *
     619   * Obtain a signal of the object type given a @name.
     620   *
     621   * `NULL` will be returned if there’s no signal available with that name.
     622   *
     623   * Returns: (transfer full) (nullable): The [class@GIRepository.SignalInfo],
     624   *   or `NULL` if no signal could be found. Free the struct by calling
     625   *   [method@GIRepository.BaseInfo.unref] when done.
     626   * Since: 2.80
     627   */
     628  GISignalInfo *
     629  gi_object_info_find_signal (GIObjectInfo *info,
     630                              const gchar  *name)
     631  {
     632    guint n_signals;
     633  
     634    n_signals = gi_object_info_get_n_signals (info);
     635    for (guint i = 0; i < n_signals; i++)
     636      {
     637        GISignalInfo *siginfo = gi_object_info_get_signal (info, i);
     638  
     639        if (g_strcmp0 (gi_base_info_get_name ((GIBaseInfo *) siginfo), name) != 0)
     640  	{
     641  	  gi_base_info_unref ((GIBaseInfo*)siginfo);
     642  	  continue;
     643  	}
     644  
     645        return siginfo;
     646      }
     647    return NULL;
     648  }
     649  
     650  
     651  /**
     652   * gi_object_info_get_n_vfuncs:
     653   * @info: a #GIObjectInfo
     654   *
     655   * Obtain the number of virtual functions that this object type has.
     656   *
     657   * Returns: number of virtual functions
     658   * Since: 2.80
     659   */
     660  guint
     661  gi_object_info_get_n_vfuncs (GIObjectInfo *info)
     662  {
     663    GIRealInfo *rinfo = (GIRealInfo *)info;
     664    ObjectBlob *blob;
     665  
     666    g_return_val_if_fail (info != NULL, 0);
     667    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     668  
     669    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     670  
     671    return blob->n_vfuncs;
     672  }
     673  
     674  /**
     675   * gi_object_info_get_vfunc:
     676   * @info: a #GIObjectInfo
     677   * @n: index of virtual function to get
     678   *
     679   * Obtain an object type virtual function at index @n.
     680   *
     681   * Returns: (transfer full): The [class@GIRepository.VFuncInfo]. Free the struct
     682   *   by calling [method@GIRepository.BaseInfo.unref] when done.
     683   * Since: 2.80
     684   */
     685  GIVFuncInfo *
     686  gi_object_info_get_vfunc (GIObjectInfo *info,
     687                            guint         n)
     688  {
     689    gint offset;
     690    GIRealInfo *rinfo = (GIRealInfo *)info;
     691    Header *header;
     692    ObjectBlob *blob;
     693  
     694    g_return_val_if_fail (info != NULL, NULL);
     695    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     696  
     697    header = (Header *)rinfo->typelib->data;
     698    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     699  
     700    offset = rinfo->offset + header->object_blob_size
     701      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     702      + blob->n_fields * header->field_blob_size
     703      + blob->n_field_callbacks * header->callback_blob_size
     704      + blob->n_properties * header->property_blob_size
     705      + blob->n_methods * header->function_blob_size
     706      + blob->n_signals * header->signal_blob_size
     707      + n * header->vfunc_blob_size;
     708  
     709    return (GIVFuncInfo *) gi_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
     710                                        rinfo->typelib, offset);
     711  }
     712  
     713  /**
     714   * gi_object_info_find_vfunc:
     715   * @info: a #GIObjectInfo
     716   * @name: the name of a virtual function to find.
     717   *
     718   * Locate a virtual function slot with name @name.
     719   *
     720   * Note that the namespace for virtuals is distinct from that of methods; there
     721   * may or may not be a concrete method associated for a virtual. If there is
     722   * one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
     723   * otherwise that method will return `NULL`.
     724   *
     725   * See the documentation for [method@GIRepository.VFuncInfo.get_invoker] for
     726   * more information on invoking virtuals.
     727   *
     728   * Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo], or
     729   *   `NULL` if none is found. Free it with [method@GIRepository.BaseInfo.unref]
     730   *   when done.
     731   * Since: 2.80
     732   */
     733  GIVFuncInfo *
     734  gi_object_info_find_vfunc (GIObjectInfo *info,
     735                             const gchar  *name)
     736  {
     737    gint offset;
     738    GIRealInfo *rinfo = (GIRealInfo *)info;
     739    Header *header;
     740    ObjectBlob *blob;
     741  
     742    g_return_val_if_fail (info != NULL, NULL);
     743    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     744  
     745    header = (Header *)rinfo->typelib->data;
     746    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     747  
     748    offset = rinfo->offset + header->object_blob_size
     749      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     750      + blob->n_fields * header->field_blob_size
     751      + blob->n_field_callbacks * header->callback_blob_size
     752      + blob->n_properties * header->property_blob_size
     753      + blob->n_methods * header->function_blob_size
     754      + blob->n_signals * header->signal_blob_size;
     755  
     756    return gi_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name);
     757  }
     758  
     759  /**
     760   * gi_object_info_find_vfunc_using_interfaces:
     761   * @info: a #GIObjectInfo
     762   * @name: name of vfunc to obtain
     763   * @implementor: (out) (transfer full) (optional) (nullable): The implementor of
     764   *   the interface, or `NULL` to ignore. If no vfunc is found, this will return
     765   *   `NULL`.
     766   *
     767   * Locate a virtual function slot with name @name, searching both the object
     768   * @info and any interfaces it implements.
     769   *
     770   * `NULL` will be returned if there’s no vfunc available with that name.
     771   *
     772   * Note that the namespace for virtuals is distinct from that of methods; there
     773   * may or may not be a concrete method associated for a virtual. If there is
     774   * one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
     775   * otherwise that method will return `NULL`.
     776   *
     777   * Note that this function does *not* search parent classes; you will have
     778   * to chain up if that’s desired.
     779   *
     780   * Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo],
     781   *   or `NULL` if none was found. Free the struct by calling
     782   *   [method@GIRepository.BaseInfo.unref] when done.
     783   * Since: 2.80
     784   */
     785  GIVFuncInfo *
     786  gi_object_info_find_vfunc_using_interfaces (GIObjectInfo  *info,
     787                                              const gchar   *name,
     788                                              GIObjectInfo **implementor)
     789  {
     790    GIVFuncInfo *result = NULL;
     791    GIObjectInfo *implementor_result = NULL;
     792  
     793    result = gi_object_info_find_vfunc (info, name);
     794    if (result)
     795      implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
     796  
     797    if (result == NULL)
     798      {
     799        int n_interfaces;
     800        int i;
     801  
     802        n_interfaces = gi_object_info_get_n_interfaces (info);
     803        for (i = 0; i < n_interfaces; ++i)
     804  	{
     805  	  GIInterfaceInfo *iface_info;
     806  
     807  	  iface_info = gi_object_info_get_interface (info, i);
     808  
     809  	  result = gi_interface_info_find_vfunc (iface_info, name);
     810  
     811  	  if (result != NULL)
     812  	    {
     813  	      implementor_result = (GIObjectInfo *) iface_info;
     814  	      break;
     815  	    }
     816  	  gi_base_info_unref ((GIBaseInfo*) iface_info);
     817  	}
     818      }
     819    if (implementor)
     820      *implementor = implementor_result;
     821    else if (implementor_result != NULL)
     822      gi_base_info_unref ((GIBaseInfo*) implementor_result);
     823    return result;
     824  }
     825  
     826  /**
     827   * gi_object_info_get_n_constants:
     828   * @info: a #GIObjectInfo
     829   *
     830   * Obtain the number of constants that this object type has.
     831   *
     832   * Returns: number of constants
     833   * Since: 2.80
     834   */
     835  guint
     836  gi_object_info_get_n_constants (GIObjectInfo *info)
     837  {
     838    GIRealInfo *rinfo = (GIRealInfo *)info;
     839    ObjectBlob *blob;
     840  
     841    g_return_val_if_fail (info != NULL, 0);
     842    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
     843  
     844    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     845  
     846    return blob->n_constants;
     847  }
     848  
     849  /**
     850   * gi_object_info_get_constant:
     851   * @info: a #GIObjectInfo
     852   * @n: index of constant to get
     853   *
     854   * Obtain an object type constant at index @n.
     855   *
     856   * Returns: (transfer full): The [class@GIRepository.ConstantInfo]. Free the
     857   *   struct by calling [method@GIRepository.BaseInfo.unref] when done.
     858   * Since: 2.80
     859   */
     860  GIConstantInfo *
     861  gi_object_info_get_constant (GIObjectInfo *info,
     862                               guint         n)
     863  {
     864    gint offset;
     865    GIRealInfo *rinfo = (GIRealInfo *)info;
     866    Header *header;
     867    ObjectBlob *blob;
     868  
     869    g_return_val_if_fail (info != NULL, NULL);
     870    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     871  
     872    header = (Header *)rinfo->typelib->data;
     873    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     874  
     875    offset = rinfo->offset + header->object_blob_size
     876      + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     877      + blob->n_fields * header->field_blob_size
     878      + blob->n_field_callbacks * header->callback_blob_size
     879      + blob->n_properties * header->property_blob_size
     880      + blob->n_methods * header->function_blob_size
     881      + blob->n_signals * header->signal_blob_size
     882      + blob->n_vfuncs * header->vfunc_blob_size
     883      + n * header->constant_blob_size;
     884  
     885    return (GIConstantInfo *) gi_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
     886                                           rinfo->typelib, offset);
     887  }
     888  
     889  /**
     890   * gi_object_info_get_class_struct:
     891   * @info: a #GIObjectInfo
     892   *
     893   * Every [class@GObject.Object] has two structures; an instance structure and a
     894   * class structure.  This function returns the metadata for the class structure.
     895   *
     896   * Returns: (transfer full) (nullable): The [class@GIRepository.StructInfo] or
     897   *   `NULL` if it’s unknown. Free with [method@GIRepository.BaseInfo.unref] when
     898   *   done.
     899   * Since: 2.80
     900   */
     901  GIStructInfo *
     902  gi_object_info_get_class_struct (GIObjectInfo *info)
     903  {
     904    GIRealInfo *rinfo = (GIRealInfo *)info;
     905    ObjectBlob *blob;
     906  
     907    g_return_val_if_fail (info != NULL, NULL);
     908    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     909  
     910    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     911  
     912    if (blob->gtype_struct)
     913      return (GIStructInfo *) gi_info_from_entry (rinfo->repository,
     914                                                  rinfo->typelib, blob->gtype_struct);
     915    else
     916      return NULL;
     917  }
     918  
     919  typedef const char* (*SymbolGetter) (GIObjectInfo *info);
     920  
     921  static void *
     922  _get_func(GIObjectInfo *info,
     923            SymbolGetter getter)
     924  {
     925    const char* symbol;
     926    GSList *parents = NULL, *l;
     927    GIObjectInfo *parent_info;
     928    gpointer func = NULL;
     929  
     930    parent_info = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo *) info);
     931    while (parent_info != NULL)
     932      {
     933        parents = g_slist_prepend (parents, parent_info);
     934        parent_info = gi_object_info_get_parent (parent_info);
     935      }
     936  
     937    for (l = parents; l; l = l->next)
     938      {
     939        parent_info = l->data;
     940        symbol = getter (parent_info);
     941        if (symbol == NULL)
     942          continue;
     943  
     944        gi_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (gpointer*) &func);
     945        if (func)
     946          break;
     947      }
     948  
     949    g_slist_free_full (parents, (GDestroyNotify) gi_base_info_unref);
     950    return func;
     951  }
     952  
     953  /**
     954   * gi_object_info_get_ref_function_name:
     955   * @info: a #GIObjectInfo
     956   *
     957   * Obtain the symbol name of the function that should be called to ref this
     958   * object type.
     959   *
     960   * It’s mainly used for fundamental types. The type signature for
     961   * the symbol is [type@GIRepository.ObjectInfoRefFunction]. To fetch the
     962   * function pointer see
     963   * [method@GIRepository.ObjectInfo.get_ref_function_pointer].
     964   *
     965   * Returns: (nullable): the symbol, or `NULL` if the object type has no ref
     966   *   function
     967   * Since: 2.80
     968   */
     969  const char *
     970  gi_object_info_get_ref_function_name (GIObjectInfo *info)
     971  {
     972    GIRealInfo *rinfo = (GIRealInfo *)info;
     973    ObjectBlob *blob;
     974  
     975    g_return_val_if_fail (info != NULL, NULL);
     976    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
     977  
     978    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
     979  
     980    if (blob->ref_func)
     981      return gi_typelib_get_string (rinfo->typelib, blob->ref_func);
     982  
     983    return NULL;
     984  }
     985  
     986  /**
     987   * gi_object_info_get_ref_function_pointer: (skip)
     988   * @info: a #GIObjectInfo
     989   *
     990   * Obtain a pointer to a function which can be used to
     991   * increase the reference count an instance of this object type.
     992   *
     993   * This takes derivation into account and will reversely traverse
     994   * the base classes of this type, starting at the top type.
     995   *
     996   * Returns: (nullable): the function pointer, or `NULL` if the object type has
     997   *   no ref function
     998   * Since: 2.80
     999   */
    1000  GIObjectInfoRefFunction
    1001  gi_object_info_get_ref_function_pointer (GIObjectInfo *info)
    1002  {
    1003    g_return_val_if_fail (info != NULL, NULL);
    1004    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1005  
    1006    return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_ref_function_name);
    1007  }
    1008  
    1009  /**
    1010   * gi_object_info_get_unref_function_name:
    1011   * @info: a #GIObjectInfo
    1012   *
    1013   * Obtain the symbol name of the function that should be called to unref this
    1014   * object type.
    1015   *
    1016   * It’s mainly used for fundamental types. The type signature for the symbol is
    1017   * [type@GIRepository.ObjectInfoUnrefFunction]. To fetch the function pointer
    1018   * see [method@GIRepository.ObjectInfo.get_unref_function_pointer].
    1019   *
    1020   * Returns: (nullable): the symbol, or `NULL` if the object type has no unref
    1021   *   function
    1022   * Since: 2.80
    1023   */
    1024  const char *
    1025  gi_object_info_get_unref_function_name (GIObjectInfo *info)
    1026  {
    1027    GIRealInfo *rinfo = (GIRealInfo *)info;
    1028    ObjectBlob *blob;
    1029  
    1030    g_return_val_if_fail (info != NULL, NULL);
    1031    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1032  
    1033    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
    1034  
    1035    if (blob->unref_func)
    1036      return gi_typelib_get_string (rinfo->typelib, blob->unref_func);
    1037  
    1038    return NULL;
    1039  }
    1040  
    1041  /**
    1042   * gi_object_info_get_unref_function_pointer: (skip)
    1043   * @info: a #GIObjectInfo
    1044   *
    1045   * Obtain a pointer to a function which can be used to
    1046   * decrease the reference count an instance of this object type.
    1047   *
    1048   * This takes derivation into account and will reversely traverse
    1049   * the base classes of this type, starting at the top type.
    1050   *
    1051   * Returns: (nullable): the function pointer, or `NULL` if the object type has
    1052   *   no unref function
    1053   * Since: 2.80
    1054   */
    1055  GIObjectInfoUnrefFunction
    1056  gi_object_info_get_unref_function_pointer (GIObjectInfo *info)
    1057  {
    1058    g_return_val_if_fail (info != NULL, NULL);
    1059    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1060  
    1061    return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_unref_function_name);
    1062  }
    1063  
    1064  /**
    1065   * gi_object_info_get_set_value_function_name:
    1066   * @info: a #GIObjectInfo
    1067   *
    1068   * Obtain the symbol name of the function that should be called to set a
    1069   * [type@GObject.Value], given an object instance pointer of this object type.
    1070   *
    1071   * It’s mainly used for fundamental types. The type signature for the symbol
    1072   * is [type@GIRepository.ObjectInfoSetValueFunction]. To fetch the function
    1073   * pointer see [method@GIRepository.ObjectInfo.get_set_value_function_pointer].
    1074   *
    1075   * Returns: (nullable): the symbol, or `NULL` if the object type has no
    1076   *   set-value function
    1077   * Since: 2.80
    1078   */
    1079  const char *
    1080  gi_object_info_get_set_value_function_name (GIObjectInfo *info)
    1081  {
    1082    GIRealInfo *rinfo = (GIRealInfo *)info;
    1083    ObjectBlob *blob;
    1084  
    1085    g_return_val_if_fail (info != NULL, NULL);
    1086    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1087  
    1088    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
    1089  
    1090    if (blob->set_value_func)
    1091      return gi_typelib_get_string (rinfo->typelib, blob->set_value_func);
    1092  
    1093    return NULL;
    1094  }
    1095  
    1096  /**
    1097   * gi_object_info_get_set_value_function_pointer: (skip)
    1098   * @info: a #GIObjectInfo
    1099   *
    1100   * Obtain a pointer to a function which can be used to set a
    1101   * [type@GObject.Value], given an instance of this object type.
    1102   *
    1103   * This takes derivation into account and will reversely traverse
    1104   * the base classes of this type, starting at the top type.
    1105   *
    1106   * Returns: (nullable): the function pointer, or `NULL` if the object type has
    1107   *   no set-value function
    1108   * Since: 2.80
    1109   */
    1110  GIObjectInfoSetValueFunction
    1111  gi_object_info_get_set_value_function_pointer (GIObjectInfo *info)
    1112  {
    1113    g_return_val_if_fail (info != NULL, NULL);
    1114    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1115  
    1116    return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_set_value_function_name);
    1117  }
    1118  
    1119  /**
    1120   * gi_object_info_get_get_value_function_name:
    1121   * @info: a #GIObjectInfo
    1122   *
    1123   * Obtain the symbol name of the function that should be called to convert
    1124   * an object instance pointer of this object type to a [type@GObject.Value].
    1125   *
    1126   * It’s mainly used for fundamental types. The type signature for the symbol
    1127   * is [type@GIRepository.ObjectInfoGetValueFunction]. To fetch the function
    1128   * pointer see [method@GIRepository.ObjectInfo.get_get_value_function_pointer].
    1129   *
    1130   * Returns: (nullable): the symbol, or `NULL` if the object type has no
    1131   *   get-value function
    1132   * Since: 2.80
    1133   */
    1134  const char *
    1135  gi_object_info_get_get_value_function_name (GIObjectInfo *info)
    1136  {
    1137    GIRealInfo *rinfo = (GIRealInfo *)info;
    1138    ObjectBlob *blob;
    1139  
    1140    g_return_val_if_fail (info != NULL, NULL);
    1141    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1142  
    1143    blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
    1144  
    1145    if (blob->get_value_func)
    1146      return gi_typelib_get_string (rinfo->typelib, blob->get_value_func);
    1147  
    1148    return NULL;
    1149  }
    1150  
    1151  /**
    1152   * gi_object_info_get_get_value_function_pointer: (skip)
    1153   * @info: a #GIObjectInfo
    1154   *
    1155   * Obtain a pointer to a function which can be used to extract an instance of
    1156   * this object type out of a [type@GObject.Value].
    1157   *
    1158   * This takes derivation into account and will reversely traverse
    1159   * the base classes of this type, starting at the top type.
    1160   *
    1161   * Returns: (nullable): the function pointer, or `NULL` if the object type has
    1162   *   no get-value function
    1163   * Since: 2.80
    1164   */
    1165  GIObjectInfoGetValueFunction
    1166  gi_object_info_get_get_value_function_pointer (GIObjectInfo *info)
    1167  {
    1168    g_return_val_if_fail (info != NULL, NULL);
    1169    g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
    1170  
    1171    return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_get_value_function_name);
    1172  }
    1173  
    1174  void
    1175  gi_object_info_class_init (gpointer g_class,
    1176                             gpointer class_data)
    1177  {
    1178    GIBaseInfoClass *info_class = g_class;
    1179  
    1180    info_class->info_type = GI_INFO_TYPE_OBJECT;
    1181  }