(root)/
glib-2.79.0/
girepository/
gitypeinfo.c
       1  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2   * GObject introspection: Type 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 "gitypeinfo.h"
      34  
      35  /**
      36   * GITypeInfo:
      37   *
      38   * `GITypeInfo` represents a type, including information about direction and
      39   * transfer.
      40   *
      41   * You can retrieve a type info from an argument (see
      42   * [class@GIRepository.ArgInfo]), a function’s return value (see
      43   * [class@GIRepository.FunctionInfo]), a field (see
      44   * [class@GIRepository.FieldInfo]), a property (see
      45   * [class@GIRepository.PropertyInfo]), a constant (see
      46   * [class@GIRepository.ConstantInfo]) or for a union discriminator (see
      47   * [class@GIRepository.UnionInfo]).
      48   *
      49   * A type can either be a of a basic type which is a standard C primitive
      50   * type or an interface type. For interface types you need to call
      51   * [method@GIRepository.TypeInfo.get_interface] to get a reference to the base
      52   * info for that interface.
      53   *
      54   * Since: 2.80
      55   */
      56  
      57  /**
      58   * gi_type_info_is_pointer:
      59   * @info: a #GITypeInfo
      60   *
      61   * Obtain if the type is passed as a reference.
      62   *
      63   * Note that the types of `GI_DIRECTION_OUT` and `GI_DIRECTION_INOUT` parameters
      64   * will only be pointers if the underlying type being transferred is a pointer
      65   * (i.e. only if the type of the C function’s formal parameter is a pointer to a
      66   * pointer).
      67   *
      68   * Returns: `TRUE` if it is a pointer
      69   * Since: 2.80
      70   */
      71  gboolean
      72  gi_type_info_is_pointer (GITypeInfo *info)
      73  {
      74    GIRealInfo *rinfo = (GIRealInfo *)info;
      75    SimpleTypeBlob *type;
      76  
      77    g_return_val_if_fail (info != NULL, FALSE);
      78    g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
      79  
      80    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
      81  
      82    if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
      83      return type->flags.pointer;
      84    else
      85      {
      86        InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
      87  
      88        return iface->pointer;
      89      }
      90  }
      91  
      92  /**
      93   * gi_type_info_get_tag:
      94   * @info: a #GITypeInfo
      95   *
      96   * Obtain the type tag for the type.
      97   *
      98   * See [type@GIRepository.TypeTag] for a list of type tags.
      99   *
     100   * Returns: the type tag
     101   * Since: 2.80
     102   */
     103  GITypeTag
     104  gi_type_info_get_tag (GITypeInfo *info)
     105  {
     106    GIRealInfo *rinfo = (GIRealInfo *)info;
     107    SimpleTypeBlob *type;
     108  
     109    g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN);
     110    g_return_val_if_fail (GI_IS_TYPE_INFO (info), GI_TYPE_TAG_BOOLEAN);
     111  
     112    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     113  
     114    if (rinfo->type_is_embedded)
     115      return GI_TYPE_TAG_INTERFACE;
     116    else if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
     117      return type->flags.tag;
     118    else
     119      {
     120        InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     121  
     122        return iface->tag;
     123      }
     124  }
     125  
     126  /**
     127   * gi_type_info_get_param_type:
     128   * @info: a #GITypeInfo
     129   * @n: index of the parameter
     130   *
     131   * Obtain the parameter type @n, or `NULL` if the type is not an array.
     132   *
     133   * Returns: (transfer full) (nullable): the param type info, or `NULL` if the
     134   *   type is not an array
     135   * Since: 2.80
     136   */
     137  GITypeInfo *
     138  gi_type_info_get_param_type (GITypeInfo *info,
     139                               guint       n)
     140  {
     141    GIRealInfo *rinfo = (GIRealInfo *)info;
     142    SimpleTypeBlob *type;
     143  
     144    g_return_val_if_fail (info != NULL, NULL);
     145    g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL);
     146  
     147    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     148  
     149    if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     150      {
     151        ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     152  
     153        switch (param->tag)
     154          {
     155            case GI_TYPE_TAG_ARRAY:
     156            case GI_TYPE_TAG_GLIST:
     157            case GI_TYPE_TAG_GSLIST:
     158            case GI_TYPE_TAG_GHASH:
     159              return gi_type_info_new ((GIBaseInfo*)info, rinfo->typelib,
     160                                       rinfo->offset + sizeof (ParamTypeBlob)
     161                                       + sizeof (SimpleTypeBlob) * n);
     162              break;
     163            default:
     164              break;
     165          }
     166      }
     167  
     168    return NULL;
     169  }
     170  
     171  /**
     172   * gi_type_info_get_interface:
     173   * @info: a #GITypeInfo
     174   *
     175   * For types which have `GI_TYPE_TAG_INTERFACE` such as [class@GObject.Object]s
     176   * and boxed values, this function returns full information about the referenced
     177   * type.
     178   *
     179   * You can then inspect the type of the returned [class@GIRepository.BaseInfo]
     180   * to further query whether it is a concrete [class@GObject.Object], an
     181   * interface, a structure, etc., using
     182   * [method@GIRepository.BaseInfo.get_info_type].
     183   *
     184   * Returns: (transfer full) (nullable): The [class@GIRepository.BaseInfo], or
     185   *   `NULL`. Free it with gi_base_info_unref() when done.
     186   * Since: 2.80
     187   */
     188  GIBaseInfo *
     189  gi_type_info_get_interface (GITypeInfo *info)
     190  {
     191    GIRealInfo *rinfo = (GIRealInfo *)info;
     192  
     193    g_return_val_if_fail (info != NULL, NULL);
     194    g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL);
     195  
     196    /* For embedded types, the given offset is a pointer to the actual blob,
     197     * after the end of the field.  In that case we know it's a "subclass" of
     198     * CommonBlob, so use that to determine the info type.
     199     */
     200    if (rinfo->type_is_embedded)
     201      {
     202        CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
     203        GIInfoType info_type;
     204  
     205        switch (common->blob_type)
     206          {
     207            case BLOB_TYPE_CALLBACK:
     208              info_type = GI_INFO_TYPE_CALLBACK;
     209              break;
     210            default:
     211              g_assert_not_reached ();
     212              return NULL;
     213          }
     214        return (GIBaseInfo *) gi_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
     215                                           rinfo->offset);
     216      }
     217    else
     218      {
     219        SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     220        if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     221          {
     222            InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     223  
     224            if (blob->tag == GI_TYPE_TAG_INTERFACE)
     225              return gi_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
     226          }
     227      }
     228  
     229    return NULL;
     230  }
     231  
     232  /**
     233   * gi_type_info_get_array_length_index:
     234   * @info: a #GITypeInfo
     235   *
     236   * Obtain the position of the argument which gives the array length of the type.
     237   *
     238   * The type tag must be a `GI_TYPE_TAG_ARRAY` or `-1` will be returned.
     239   *
     240   * Returns: the array length argument index, or `-1` if the type is not an array
     241   *   or it has no length argument
     242   * Since: 2.80
     243   */
     244  gint
     245  gi_type_info_get_array_length_index (GITypeInfo *info)
     246  {
     247    GIRealInfo *rinfo = (GIRealInfo *)info;
     248    SimpleTypeBlob *type;
     249  
     250    g_return_val_if_fail (info != NULL, -1);
     251    g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1);
     252  
     253    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     254  
     255    if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     256      {
     257        ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     258  
     259        if (blob->tag == GI_TYPE_TAG_ARRAY)
     260  	{
     261  	  if (blob->has_length)
     262  	    return blob->dimensions.length;
     263  	}
     264      }
     265  
     266    return -1;
     267  }
     268  
     269  /**
     270   * gi_type_info_get_array_fixed_size:
     271   * @info: a #GITypeInfo
     272   *
     273   * Obtain the fixed array size of the type, in number of elements (not bytes).
     274   *
     275   * The type tag must be a `GI_TYPE_TAG_ARRAY` or `-1` will be returned.
     276   *
     277   * Returns: the size or `-1` if the type is not an array or it has no fixed size
     278   * Since: 2.80
     279   */
     280  gssize
     281  gi_type_info_get_array_fixed_size (GITypeInfo *info)
     282  {
     283    GIRealInfo *rinfo = (GIRealInfo *)info;
     284    SimpleTypeBlob *type;
     285  
     286    g_return_val_if_fail (info != NULL, -1);
     287    g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1);
     288  
     289    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     290  
     291    if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     292      {
     293        ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     294  
     295        if (blob->tag == GI_TYPE_TAG_ARRAY)
     296  	{
     297  	  if (blob->has_size)
     298  	    return blob->dimensions.size;
     299  	}
     300      }
     301  
     302    return -1;
     303  }
     304  
     305  /**
     306   * gi_type_info_is_zero_terminated:
     307   * @info: a #GITypeInfo
     308   *
     309   * Obtain if the last element of the array is `NULL`.
     310   *
     311   * The type tag must be a `GI_TYPE_TAG_ARRAY` or `FALSE` will be returned.
     312   *
     313   * Returns: `TRUE` if zero terminated
     314   * Since: 2.80
     315   */
     316  gboolean
     317  gi_type_info_is_zero_terminated (GITypeInfo *info)
     318  {
     319    GIRealInfo *rinfo = (GIRealInfo *)info;
     320    SimpleTypeBlob *type;
     321  
     322    g_return_val_if_fail (info != NULL, FALSE);
     323    g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
     324  
     325    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     326  
     327    if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     328      {
     329        ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     330  
     331        if (blob->tag == GI_TYPE_TAG_ARRAY)
     332  	return blob->zero_terminated;
     333      }
     334  
     335    return FALSE;
     336  }
     337  
     338  /**
     339   * gi_type_info_get_array_type:
     340   * @info: a #GITypeInfo
     341   *
     342   * Obtain the array type for this type.
     343   *
     344   * See [enum@GIRepository.ArrayType] for a list of possible values. If the type
     345   * tag of this type is not array, `-1` will be returned.
     346   *
     347   * Returns: the array type or `-1`
     348   * Since: 2.80
     349   */
     350  GIArrayType
     351  gi_type_info_get_array_type (GITypeInfo *info)
     352  {
     353    GIRealInfo *rinfo = (GIRealInfo *)info;
     354    SimpleTypeBlob *type;
     355  
     356    g_return_val_if_fail (info != NULL, -1);
     357    g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1);
     358  
     359    type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     360  
     361    if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     362      {
     363        ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
     364        g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1);
     365  
     366        return blob->array_type;
     367      }
     368  
     369    return -1;
     370  }
     371  
     372  /**
     373   * gi_type_info_get_storage_type:
     374   * @info: a #GITypeInfo
     375   *
     376   * Obtain the type tag corresponding to the underlying storage type in C for
     377   * the type.
     378   *
     379   * See [type@GIRepository.TypeTag] for a list of type tags.
     380   *
     381   * Returns: the type tag
     382   * Since: 2.80
     383   */
     384  GITypeTag
     385  gi_type_info_get_storage_type (GITypeInfo *info)
     386  {
     387    GITypeTag type_tag = gi_type_info_get_tag (info);
     388  
     389    if (type_tag == GI_TYPE_TAG_INTERFACE)
     390      {
     391        GIBaseInfo *interface = gi_type_info_get_interface (info);
     392        GIInfoType info_type = gi_base_info_get_info_type (interface);
     393        if (info_type == GI_INFO_TYPE_ENUM || info_type == GI_INFO_TYPE_FLAGS)
     394          type_tag = gi_enum_info_get_storage_type ((GIEnumInfo *) interface);
     395        gi_base_info_unref (interface);
     396      }
     397  
     398    return type_tag;
     399  }
     400  
     401  /**
     402   * gi_type_tag_argument_from_hash_pointer:
     403   * @storage_type: a [type@GIRepository.TypeTag] obtained from
     404   *   [method@GIRepository.TypeInfo.get_storage_type]
     405   * @hash_pointer: a pointer, such as a [struct@GLib.HashTable] data pointer
     406   * @arg: (out caller-allocates) (not nullable): a [type@GIRepository.Argument]
     407   *   to fill in
     408   *
     409   * Convert a data pointer from a GLib data structure to a
     410   * [type@GIRepository.Argument].
     411   *
     412   * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
     413   * [type@GLib.HashTable], all store data pointers.
     414   *
     415   * In the case where the list or hash table is storing single types rather than
     416   * structs, these data pointers may have values stuffed into them via macros
     417   * such as `GPOINTER_TO_INT`.
     418   *
     419   * Use this function to ensure that all values are correctly extracted from
     420   * stuffed pointers, regardless of the machine’s architecture or endianness.
     421   *
     422   * This function fills in the appropriate field of @arg with the value extracted
     423   * from @hash_pointer, depending on @storage_type.
     424   *
     425   * Since: 2.80
     426   */
     427  void
     428  gi_type_tag_argument_from_hash_pointer (GITypeTag   storage_type,
     429                                          gpointer    hash_pointer,
     430                                          GIArgument *arg)
     431  {
     432    switch (storage_type)
     433      {
     434        case GI_TYPE_TAG_BOOLEAN:
     435          arg->v_boolean = !!GPOINTER_TO_INT (hash_pointer);
     436          break;
     437        case GI_TYPE_TAG_INT8:
     438          arg->v_int8 = (gint8)GPOINTER_TO_INT (hash_pointer);
     439          break;
     440        case GI_TYPE_TAG_UINT8:
     441          arg->v_uint8 = (guint8)GPOINTER_TO_UINT (hash_pointer);
     442          break;
     443        case GI_TYPE_TAG_INT16:
     444          arg->v_int16 = (gint16)GPOINTER_TO_INT (hash_pointer);
     445          break;
     446        case GI_TYPE_TAG_UINT16:
     447          arg->v_uint16 = (guint16)GPOINTER_TO_UINT (hash_pointer);
     448          break;
     449        case GI_TYPE_TAG_INT32:
     450          arg->v_int32 = (gint32)GPOINTER_TO_INT (hash_pointer);
     451          break;
     452        case GI_TYPE_TAG_UINT32:
     453        case GI_TYPE_TAG_UNICHAR:
     454          arg->v_uint32 = (guint32)GPOINTER_TO_UINT (hash_pointer);
     455          break;
     456        case GI_TYPE_TAG_GTYPE:
     457          arg->v_size = GPOINTER_TO_SIZE (hash_pointer);
     458          break;
     459        case GI_TYPE_TAG_UTF8:
     460        case GI_TYPE_TAG_FILENAME:
     461        case GI_TYPE_TAG_INTERFACE:
     462        case GI_TYPE_TAG_ARRAY:
     463        case GI_TYPE_TAG_GLIST:
     464        case GI_TYPE_TAG_GSLIST:
     465        case GI_TYPE_TAG_GHASH:
     466        case GI_TYPE_TAG_ERROR:
     467          arg->v_pointer = hash_pointer;
     468          break;
     469        case GI_TYPE_TAG_INT64:
     470        case GI_TYPE_TAG_UINT64:
     471        case GI_TYPE_TAG_FLOAT:
     472        case GI_TYPE_TAG_DOUBLE:
     473        default:
     474          g_critical ("Unsupported storage type for pointer-stuffing: %s",
     475                      gi_type_tag_to_string (storage_type));
     476          arg->v_pointer = hash_pointer;
     477      }
     478  }
     479  
     480  /**
     481   * gi_type_info_argument_from_hash_pointer:
     482   * @info: a #GITypeInfo
     483   * @hash_pointer: a pointer, such as a [struct@GLib.HashTable] data pointer
     484   * @arg: (out caller-allocates): a [type@GIRepository.Argument] to fill in
     485   *
     486   * Convert a data pointer from a GLib data structure to a
     487   * [type@GIRepository.Argument].
     488   *
     489   * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
     490   * [type@GLib.HashTable], all store data pointers.
     491   *
     492   * In the case where the list or hash table is storing single types rather than
     493   * structs, these data pointers may have values stuffed into them via macros
     494   * such as `GPOINTER_TO_INT`.
     495   *
     496   * Use this function to ensure that all values are correctly extracted from
     497   * stuffed pointers, regardless of the machine’s architecture or endianness.
     498   *
     499   * This function fills in the appropriate field of @arg with the value extracted
     500   * from @hash_pointer, depending on the storage type of @info.
     501   *
     502   * Since: 2.80
     503   */
     504  void
     505  gi_type_info_argument_from_hash_pointer (GITypeInfo *info,
     506                                           gpointer    hash_pointer,
     507                                           GIArgument *arg)
     508  {
     509      GITypeTag storage_type = gi_type_info_get_storage_type (info);
     510      gi_type_tag_argument_from_hash_pointer (storage_type, hash_pointer,
     511                                              arg);
     512  }
     513  
     514  /**
     515   * gi_type_tag_hash_pointer_from_argument:
     516   * @storage_type: a [type@GIRepository.TypeTag] obtained from
     517   *   [method@GIRepository.TypeInfo.get_storage_type]
     518   * @arg: a [type@GIRepository.Argument] with the value to stuff into a pointer
     519   *
     520   * Convert a [type@GIRepository.Argument] to data pointer for use in a GLib
     521   * data structure.
     522   *
     523   * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
     524   * [type@GLib.HashTable], all store data pointers.
     525   *
     526   * In the case where the list or hash table is storing single types rather than
     527   * structs, these data pointers may have values stuffed into them via macros
     528   * such as `GPOINTER_TO_INT`.
     529   *
     530   * Use this function to ensure that all values are correctly stuffed into
     531   * pointers, regardless of the machine’s architecture or endianness.
     532   *
     533   * This function returns a pointer stuffed with the appropriate field of @arg,
     534   * depending on @storage_type.
     535   *
     536   * Returns: A stuffed pointer, that can be stored in a [struct@GLib.HashTable],
     537   *   for example
     538   * Since: 2.80
     539   */
     540  gpointer
     541  gi_type_tag_hash_pointer_from_argument (GITypeTag   storage_type,
     542                                          GIArgument *arg)
     543  {
     544    switch (storage_type)
     545      {
     546        case GI_TYPE_TAG_BOOLEAN:
     547          return GINT_TO_POINTER (arg->v_boolean);
     548        case GI_TYPE_TAG_INT8:
     549          return GINT_TO_POINTER (arg->v_int8);
     550        case GI_TYPE_TAG_UINT8:
     551          return GUINT_TO_POINTER (arg->v_uint8);
     552        case GI_TYPE_TAG_INT16:
     553          return GINT_TO_POINTER (arg->v_int16);
     554        case GI_TYPE_TAG_UINT16:
     555          return GUINT_TO_POINTER (arg->v_uint16);
     556        case GI_TYPE_TAG_INT32:
     557          return GINT_TO_POINTER (arg->v_int32);
     558        case GI_TYPE_TAG_UINT32:
     559        case GI_TYPE_TAG_UNICHAR:
     560          return GUINT_TO_POINTER (arg->v_uint32);
     561        case GI_TYPE_TAG_GTYPE:
     562          return GSIZE_TO_POINTER (arg->v_size);
     563        case GI_TYPE_TAG_UTF8:
     564        case GI_TYPE_TAG_FILENAME:
     565        case GI_TYPE_TAG_INTERFACE:
     566        case GI_TYPE_TAG_ARRAY:
     567        case GI_TYPE_TAG_GLIST:
     568        case GI_TYPE_TAG_GSLIST:
     569        case GI_TYPE_TAG_GHASH:
     570        case GI_TYPE_TAG_ERROR:
     571          return arg->v_pointer;
     572        case GI_TYPE_TAG_INT64:
     573        case GI_TYPE_TAG_UINT64:
     574        case GI_TYPE_TAG_FLOAT:
     575        case GI_TYPE_TAG_DOUBLE:
     576        default:
     577          g_critical ("Unsupported storage type for pointer-stuffing: %s",
     578                      gi_type_tag_to_string (storage_type));
     579          return arg->v_pointer;
     580      }
     581  }
     582  
     583  /**
     584   * gi_type_info_hash_pointer_from_argument:
     585   * @info: a #GITypeInfo
     586   * @arg: a [struct@GIRepository.Argument] with the value to stuff into a pointer
     587   *
     588   * Convert a [type@GIRepository.Argument] to data pointer for use in a GLib
     589   * data structure.
     590   *
     591   * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
     592   * [type@GLib.HashTable], all store data pointers.
     593   *
     594   * In the case where the list or hash table is storing single types rather than
     595   * structs, these data pointers may have values stuffed into them via macros
     596   * such as `GPOINTER_TO_INT`.
     597   *
     598   * Use this function to ensure that all values are correctly stuffed into
     599   * pointers, regardless of the machine’s architecture or endianness.
     600   *
     601   * This function returns a pointer stuffed with the appropriate field of @arg,
     602   * depending on the storage type of @info.
     603   *
     604   * Returns: A stuffed pointer, that can be stored in a [struct@GLib.HashTable],
     605   *   for example
     606   * Since: 2.80
     607   */
     608  gpointer
     609  gi_type_info_hash_pointer_from_argument (GITypeInfo *info,
     610                                           GIArgument *arg)
     611  {
     612    GITypeTag storage_type = gi_type_info_get_storage_type (info);
     613    return gi_type_tag_hash_pointer_from_argument (storage_type, arg);
     614  }
     615  
     616  void
     617  gi_type_info_class_init (gpointer g_class,
     618                           gpointer class_data)
     619  {
     620    GIBaseInfoClass *info_class = g_class;
     621  
     622    info_class->info_type = GI_INFO_TYPE_TYPE;
     623  }