/**
 * g_interface_info_get_prerequisite:
 * @info: a #GIInterfaceInfo
 * @n: index of prerequisites to get
 *
 * Obtain an interface type prerequisites index @n.
 *
 * Returns: (transfer full): the prerequisites as a #GIBaseInfo. Free the struct by calling
 * g_base_info_unref() when done.
 */
GIBaseInfo *
g_interface_info_get_prerequisite (GIInterfaceInfo *info,
                                   gint            n)
{
    GIRealInfo *rinfo = (GIRealInfo *)info;
    InterfaceBlob *blob;

    g_return_val_if_fail (info != NULL, NULL);
    g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);

    blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];

    return _g_info_from_entry (rinfo->repository,
                               rinfo->typelib, blob->prerequisites[n]);
}
/**
 * g_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 #GIInterfaceInfo. Free the struct by calling
 * g_base_info_unref() when done.
 */
GIInterfaceInfo *
g_object_info_get_interface (GIObjectInfo *info,
			     gint          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);

  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];

  return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository,
						 rinfo->typelib, blob->interfaces[n]);
}
/**
 * g_object_info_get_parent:
 * @info: a #GIObjectInfo
 *
 * Obtain the parent of the object type.
 *
 * Returns: (transfer full): the #GIObjectInfo. Free the struct by calling
 * g_base_info_unref() when done.
 */
GIObjectInfo *
g_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 *) _g_info_from_entry (rinfo->repository,
                                                rinfo->typelib, blob->parent);
  else
    return NULL;
}
/**
 * g_interface_info_get_iface_struct:
 * @info: a #GIInterfaceInfo
 *
 * Returns the layout C structure associated with this #GInterface.
 *
 * Returns: (transfer full): the #GIStructInfo or %NULL. Free it with
 * g_base_info_unref() when done.
 */
GIStructInfo *
g_interface_info_get_iface_struct (GIInterfaceInfo *info)
{
    GIRealInfo *rinfo = (GIRealInfo *)info;
    InterfaceBlob *blob;

    g_return_val_if_fail (info != NULL, NULL);
    g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL);

    blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];

    if (blob->gtype_struct)
        return (GIStructInfo *) _g_info_from_entry (rinfo->repository,
                rinfo->typelib, blob->gtype_struct);
    else
        return NULL;
}
/**
 * g_type_info_get_interface:
 * @info: a #GITypeInfo
 *
 * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values,
 * this function returns full information about the referenced type.  You can then
 * inspect the type of the returned #GIBaseInfo to further query whether it is
 * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type().
 *
 * Returns: (transfer full): the #GIBaseInfo, or %NULL. Free it with
 * g_base_info_unref() when done.
 */
GIBaseInfo *
g_type_info_get_interface (GITypeInfo *info)
{
  GIRealInfo *rinfo = (GIRealInfo *)info;

  g_return_val_if_fail (info != NULL, NULL);
  g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL);

  /* For embedded types, the given offset is a pointer to the actual blob,
   * after the end of the field.  In that case we know it's a "subclass" of
   * CommonBlob, so use that to determine the info type.
   */
  if (rinfo->type_is_embedded)
    {
      CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
      GIInfoType info_type;

      switch (common->blob_type)
        {
          case BLOB_TYPE_CALLBACK:
            info_type = GI_INFO_TYPE_CALLBACK;
            break;
          default:
            g_assert_not_reached ();
            return NULL;
        }
      return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
                                        rinfo->offset);
    }
  else
    {
      SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
      if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
        {
          InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];

          if (blob->tag == GI_TYPE_TAG_INTERFACE)
            return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
        }
    }

  return NULL;
}