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