2012-02-03 19:42:56 +01:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
|
|
* GObject introspection: Field implementation
|
2010-06-06 18:11:23 +02:00
|
|
|
*
|
|
|
|
* Copyright (C) 2005 Matthias Clasen
|
|
|
|
* Copyright (C) 2008,2009 Red Hat, Inc.
|
|
|
|
*
|
2023-10-25 18:10:10 +02:00
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
*
|
2010-06-06 18:11:23 +02:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2014-07-04 12:27:41 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2010-06-06 18:11:23 +02:00
|
|
|
#include <glib.h>
|
|
|
|
|
2023-10-25 18:45:42 +02:00
|
|
|
#include <girepository/girepository.h>
|
2023-11-28 18:24:20 +01:00
|
|
|
#include "gibaseinfo-private.h"
|
2010-06-06 18:11:23 +02:00
|
|
|
#include "girepository-private.h"
|
|
|
|
#include "gitypelib-internal.h"
|
2010-06-06 18:15:14 +02:00
|
|
|
#include "config.h"
|
2023-10-25 19:11:38 +02:00
|
|
|
#include "gifieldinfo.h"
|
2010-06-06 18:11:23 +02:00
|
|
|
|
|
|
|
/**
|
2023-11-28 18:27:34 +01:00
|
|
|
* GIFieldInfo:
|
2010-06-06 18:11:23 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* A `GIFieldInfo` struct represents a field of a struct, union, or object.
|
2022-02-13 15:20:51 +01:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* The `GIFieldInfo` is fetched by calling
|
|
|
|
* [method@GIRepository.StructInfo.get_field],
|
|
|
|
* [method@GIRepository.UnionInfo.get_field] or
|
|
|
|
* [method@GIRepository.ObjectInfo.get_field].
|
2022-02-13 15:20:51 +01:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* A field has a size, type and a struct offset associated and a set of flags,
|
|
|
|
* which are currently `GI_FIELD_IS_READABLE` or `GI_FIELD_IS_WRITABLE`.
|
2010-06-12 01:16:00 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* See also: [type@GIRepository.StructInfo], [type@GIRepository.UnionInfo],
|
|
|
|
* [type@GIRepository.ObjectInfo]
|
|
|
|
*
|
|
|
|
* Since: 2.80
|
2010-06-06 18:11:23 +02:00
|
|
|
*/
|
|
|
|
|
2010-06-07 03:47:50 +02:00
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
* gi_field_info_get_flags:
|
2010-06-07 03:47:50 +02:00
|
|
|
* @info: a #GIFieldInfo
|
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Obtain the flags for this `GIFieldInfo`. See
|
|
|
|
* [flags@GIRepository.FieldInfoFlags] for possible flag values.
|
2010-06-07 03:47:50 +02:00
|
|
|
*
|
|
|
|
* Returns: the flags
|
2023-11-28 18:27:34 +01:00
|
|
|
* Since: 2.80
|
2010-06-07 03:47:50 +02:00
|
|
|
*/
|
2010-06-06 18:11:23 +02:00
|
|
|
GIFieldInfoFlags
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_field_info_get_flags (GIFieldInfo *info)
|
2010-06-06 18:11:23 +02:00
|
|
|
{
|
|
|
|
GIFieldInfoFlags flags;
|
|
|
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
2010-06-06 18:35:14 +02:00
|
|
|
FieldBlob *blob;
|
|
|
|
|
|
|
|
g_return_val_if_fail (info != NULL, 0);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
|
|
|
|
|
|
|
|
blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
|
2010-06-06 18:11:23 +02:00
|
|
|
|
|
|
|
flags = 0;
|
|
|
|
|
|
|
|
if (blob->readable)
|
|
|
|
flags = flags | GI_FIELD_IS_READABLE;
|
|
|
|
|
|
|
|
if (blob->writable)
|
|
|
|
flags = flags | GI_FIELD_IS_WRITABLE;
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
* gi_field_info_get_size:
|
2010-06-06 18:35:14 +02:00
|
|
|
* @info: a #GIFieldInfo
|
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Obtain the size of the field member, in bits. This is how
|
2010-06-06 18:35:14 +02:00
|
|
|
* much space you need to allocate to store the field.
|
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Returns: the field size, in bits
|
|
|
|
* Since: 2.80
|
2010-06-06 18:35:14 +02:00
|
|
|
*/
|
2010-06-06 18:11:23 +02:00
|
|
|
gint
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_field_info_get_size (GIFieldInfo *info)
|
2010-06-06 18:11:23 +02:00
|
|
|
{
|
|
|
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
2010-06-06 18:35:14 +02:00
|
|
|
FieldBlob *blob;
|
|
|
|
|
|
|
|
g_return_val_if_fail (info != NULL, 0);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
|
|
|
|
|
|
|
|
blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
|
2010-06-06 18:11:23 +02:00
|
|
|
|
|
|
|
return blob->bits;
|
|
|
|
}
|
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
* gi_field_info_get_offset:
|
2010-06-06 18:35:14 +02:00
|
|
|
* @info: a #GIFieldInfo
|
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Obtain the offset of the field member, in bytes. This is relative
|
2010-06-06 18:35:14 +02:00
|
|
|
* to the beginning of the struct or union.
|
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Returns: the field offset, in bytes
|
|
|
|
* Since: 2.80
|
2010-06-06 18:35:14 +02:00
|
|
|
*/
|
2010-06-06 18:11:23 +02:00
|
|
|
gint
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_field_info_get_offset (GIFieldInfo *info)
|
2010-06-06 18:11:23 +02:00
|
|
|
{
|
|
|
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
2010-06-06 18:35:14 +02:00
|
|
|
FieldBlob *blob;
|
|
|
|
|
|
|
|
g_return_val_if_fail (info != NULL, 0);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
|
|
|
|
|
|
|
|
blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
|
2010-06-06 18:11:23 +02:00
|
|
|
|
|
|
|
return blob->struct_offset;
|
|
|
|
}
|
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
/**
|
2023-11-28 18:09:26 +01:00
|
|
|
* gi_field_info_get_type_info:
|
2010-06-07 03:47:50 +02:00
|
|
|
* @info: a #GIFieldInfo
|
2010-06-06 18:35:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Obtain the type of a field as a [type@GIRepository.TypeInfo].
|
2010-06-06 18:35:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Returns: (transfer full): the [type@GIRepository.TypeInfo]. Free the struct
|
|
|
|
* by calling [method@GIRepository.BaseInfo.unref] when done.
|
2010-06-06 18:35:14 +02:00
|
|
|
*/
|
2010-06-06 18:11:23 +02:00
|
|
|
GITypeInfo *
|
2023-11-28 18:09:26 +01:00
|
|
|
gi_field_info_get_type_info (GIFieldInfo *info)
|
2010-06-06 18:11:23 +02:00
|
|
|
{
|
|
|
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
|
|
|
Header *header = (Header *)rinfo->typelib->data;
|
2010-06-06 18:35:14 +02:00
|
|
|
FieldBlob *blob;
|
2010-06-06 18:11:23 +02:00
|
|
|
GIRealInfo *type_info;
|
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
g_return_val_if_fail (info != NULL, NULL);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (info), NULL);
|
|
|
|
|
|
|
|
blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
|
|
|
|
|
2010-06-06 18:11:23 +02:00
|
|
|
if (blob->has_embedded_type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
type_info = (GIRealInfo *) gi_info_new (GI_INFO_TYPE_TYPE,
|
|
|
|
(GIBaseInfo*)info, rinfo->typelib,
|
|
|
|
rinfo->offset + header->field_blob_size);
|
2010-06-06 18:11:23 +02:00
|
|
|
type_info->type_is_embedded = TRUE;
|
|
|
|
}
|
|
|
|
else
|
2023-11-08 16:23:31 +01:00
|
|
|
return gi_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type));
|
2010-06-06 18:11:23 +02:00
|
|
|
|
2023-11-28 18:14:30 +01:00
|
|
|
return (GITypeInfo *) type_info;
|
2010-06-06 18:11:23 +02:00
|
|
|
}
|
|
|
|
|
2010-06-06 18:15:14 +02:00
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
* gi_field_info_get_field: (skip)
|
2010-06-06 18:15:14 +02:00
|
|
|
* @field_info: a #GIFieldInfo
|
|
|
|
* @mem: pointer to a block of memory representing a C structure or union
|
2023-11-28 18:27:34 +01:00
|
|
|
* @value: a [type@GIRepository.Argument] into which to store the value retrieved
|
|
|
|
*
|
|
|
|
* Reads a field identified by a `GIFieldInfo` from a C structure or
|
|
|
|
* union.
|
2010-06-06 18:15:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* This only handles fields of simple C types. It will fail for a field of a
|
|
|
|
* composite type like a nested structure or union even if that is actually
|
|
|
|
* readable.
|
2010-06-06 18:15:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Returns: true if reading the field succeeded, false otherwise
|
|
|
|
* Since: 2.80
|
2010-06-06 18:15:14 +02:00
|
|
|
*/
|
|
|
|
gboolean
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_field_info_get_field (GIFieldInfo *field_info,
|
|
|
|
gpointer mem,
|
|
|
|
GIArgument *value)
|
2010-06-06 18:15:14 +02:00
|
|
|
{
|
2010-06-06 18:35:14 +02:00
|
|
|
int offset;
|
|
|
|
GITypeInfo *type_info;
|
|
|
|
gboolean result = FALSE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (field_info != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE);
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
if ((gi_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0)
|
2010-06-06 18:35:14 +02:00
|
|
|
return FALSE;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
offset = gi_field_info_get_offset (field_info);
|
2023-11-28 18:09:26 +01:00
|
|
|
type_info = gi_field_info_get_type_info (field_info);
|
2010-06-06 18:35:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
if (gi_type_info_is_pointer (type_info))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
2011-06-05 20:57:01 +02:00
|
|
|
value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset);
|
2010-06-06 18:35:14 +02:00
|
|
|
result = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
switch (gi_type_info_get_tag (type_info))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_VOID:
|
|
|
|
g_warning("Field %s: should not be have void type",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_BOOLEAN:
|
|
|
|
value->v_boolean = G_STRUCT_MEMBER (gboolean, mem, offset) != FALSE;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT8:
|
|
|
|
case GI_TYPE_TAG_UINT8:
|
|
|
|
value->v_uint8 = G_STRUCT_MEMBER (guint8, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT16:
|
|
|
|
case GI_TYPE_TAG_UINT16:
|
|
|
|
value->v_uint16 = G_STRUCT_MEMBER (guint16, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT32:
|
|
|
|
case GI_TYPE_TAG_UINT32:
|
2010-10-26 17:12:26 +02:00
|
|
|
case GI_TYPE_TAG_UNICHAR:
|
2010-06-06 18:35:14 +02:00
|
|
|
value->v_uint32 = G_STRUCT_MEMBER (guint32, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT64:
|
|
|
|
case GI_TYPE_TAG_UINT64:
|
|
|
|
value->v_uint64 = G_STRUCT_MEMBER (guint64, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_GTYPE:
|
|
|
|
value->v_size = G_STRUCT_MEMBER (gsize, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_FLOAT:
|
|
|
|
value->v_float = G_STRUCT_MEMBER (gfloat, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_DOUBLE:
|
|
|
|
value->v_double = G_STRUCT_MEMBER (gdouble, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
2011-06-05 20:57:01 +02:00
|
|
|
case GI_TYPE_TAG_ARRAY:
|
|
|
|
/* We don't check the array type and that it is fixed-size,
|
|
|
|
we trust g-ir-compiler to do the right thing */
|
|
|
|
value->v_pointer = G_STRUCT_MEMBER_P (mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
2010-06-06 18:35:14 +02:00
|
|
|
case GI_TYPE_TAG_UTF8:
|
|
|
|
case GI_TYPE_TAG_FILENAME:
|
|
|
|
case GI_TYPE_TAG_GLIST:
|
|
|
|
case GI_TYPE_TAG_GSLIST:
|
|
|
|
case GI_TYPE_TAG_GHASH:
|
|
|
|
g_warning("Field %s: type %s should have is_pointer set",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
|
|
|
gi_type_tag_to_string (gi_type_info_get_tag (type_info)));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_ERROR:
|
|
|
|
/* Needs to be handled by the language binding directly */
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIBaseInfo *interface = gi_type_info_get_interface (type_info);
|
2023-12-12 17:16:30 +01:00
|
|
|
switch (gi_base_info_get_info_type (interface))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
|
|
|
case GI_INFO_TYPE_STRUCT:
|
|
|
|
case GI_INFO_TYPE_UNION:
|
|
|
|
case GI_INFO_TYPE_BOXED:
|
|
|
|
/* Needs to be handled by the language binding directly */
|
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_OBJECT:
|
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_ENUM:
|
|
|
|
case GI_INFO_TYPE_FLAGS:
|
2010-06-06 18:15:14 +02:00
|
|
|
{
|
2010-06-06 18:35:14 +02:00
|
|
|
/* FIXME: there's a mismatch here between the value->v_int we use
|
2023-11-08 15:17:52 +01:00
|
|
|
* here and the gint64 result returned from gi_value_info_get_value().
|
|
|
|
* But to switch this to gint64, we'd have to make gi_function_info_invoke()
|
2010-09-14 17:59:03 +02:00
|
|
|
* translate value->v_int64 to the proper ABI for an enum function
|
2010-06-06 18:35:14 +02:00
|
|
|
* call parameter, which will usually be int, and then fix up language
|
|
|
|
* bindings.
|
|
|
|
*/
|
2023-11-08 15:17:52 +01:00
|
|
|
GITypeTag storage_type = gi_enum_info_get_storage_type ((GIEnumInfo *)interface);
|
2010-06-06 18:35:14 +02:00
|
|
|
switch (storage_type)
|
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_INT8:
|
|
|
|
case GI_TYPE_TAG_UINT8:
|
|
|
|
value->v_int = (gint)G_STRUCT_MEMBER (guint8, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT16:
|
|
|
|
case GI_TYPE_TAG_UINT16:
|
|
|
|
value->v_int = (gint)G_STRUCT_MEMBER (guint16, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT32:
|
|
|
|
case GI_TYPE_TAG_UINT32:
|
|
|
|
value->v_int = (gint)G_STRUCT_MEMBER (guint32, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT64:
|
|
|
|
case GI_TYPE_TAG_UINT64:
|
|
|
|
value->v_int = (gint)G_STRUCT_MEMBER (guint64, mem, offset);
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_warning("Field %s: Unexpected enum storage type %s",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
|
|
|
gi_type_tag_to_string (storage_type));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:35:14 +02:00
|
|
|
case GI_INFO_TYPE_VFUNC:
|
|
|
|
case GI_INFO_TYPE_CALLBACK:
|
|
|
|
g_warning("Field %s: Interface type %d should have is_pointer set",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
2023-12-12 17:16:30 +01:00
|
|
|
gi_base_info_get_info_type (interface));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_INVALID:
|
|
|
|
case GI_INFO_TYPE_INTERFACE:
|
|
|
|
case GI_INFO_TYPE_FUNCTION:
|
|
|
|
case GI_INFO_TYPE_CONSTANT:
|
2011-05-19 22:12:03 +02:00
|
|
|
case GI_INFO_TYPE_INVALID_0:
|
2010-06-06 18:35:14 +02:00
|
|
|
case GI_INFO_TYPE_VALUE:
|
|
|
|
case GI_INFO_TYPE_SIGNAL:
|
|
|
|
case GI_INFO_TYPE_PROPERTY:
|
|
|
|
case GI_INFO_TYPE_FIELD:
|
|
|
|
case GI_INFO_TYPE_ARG:
|
|
|
|
case GI_INFO_TYPE_TYPE:
|
|
|
|
case GI_INFO_TYPE_UNRESOLVED:
|
|
|
|
g_warning("Field %s: Interface type %d not expected",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
2023-12-12 17:16:30 +01:00
|
|
|
gi_base_info_get_info_type (interface));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
2018-07-29 17:13:16 +02:00
|
|
|
default:
|
|
|
|
break;
|
2010-06-06 18:35:14 +02:00
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_unref ((GIBaseInfo *)interface);
|
2010-06-06 18:15:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
2018-07-29 17:13:16 +02:00
|
|
|
default:
|
|
|
|
break;
|
2010-06-06 18:35:14 +02:00
|
|
|
}
|
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_unref ((GIBaseInfo *)type_info);
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
return result;
|
2010-06-06 18:15:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-11-08 15:17:52 +01:00
|
|
|
* gi_field_info_set_field: (skip)
|
2010-06-06 18:15:14 +02:00
|
|
|
* @field_info: a #GIFieldInfo
|
|
|
|
* @mem: pointer to a block of memory representing a C structure or union
|
2023-11-28 18:27:34 +01:00
|
|
|
* @value: a [type@GIRepository.Argument] holding the value to store
|
|
|
|
*
|
|
|
|
* Writes a field identified by a `GIFieldInfo` to a C structure or
|
|
|
|
* union.
|
2010-06-06 18:15:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* This only handles fields of simple C types. It will fail for a field of a
|
|
|
|
* composite type like a nested structure or union even if that is actually
|
|
|
|
* writable. Note also that that it will refuse to write fields where memory
|
|
|
|
* management would by required. A field with a type such as `char *` must be
|
|
|
|
* set with a setter function.
|
2010-06-06 18:15:14 +02:00
|
|
|
*
|
2023-11-28 18:27:34 +01:00
|
|
|
* Returns: true if writing the field succeeded, false otherwise
|
|
|
|
* Since: 2.80
|
2010-06-06 18:15:14 +02:00
|
|
|
*/
|
|
|
|
gboolean
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_field_info_set_field (GIFieldInfo *field_info,
|
|
|
|
gpointer mem,
|
|
|
|
const GIArgument *value)
|
2010-06-06 18:15:14 +02:00
|
|
|
{
|
2010-06-06 18:35:14 +02:00
|
|
|
int offset;
|
|
|
|
GITypeInfo *type_info;
|
|
|
|
gboolean result = FALSE;
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
g_return_val_if_fail (field_info != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE);
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
if ((gi_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0)
|
2010-06-06 18:35:14 +02:00
|
|
|
return FALSE;
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
offset = gi_field_info_get_offset (field_info);
|
2023-11-28 18:09:26 +01:00
|
|
|
type_info = gi_field_info_get_type_info (field_info);
|
2010-06-06 18:35:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
if (!gi_type_info_is_pointer (type_info))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
switch (gi_type_info_get_tag (type_info))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_VOID:
|
|
|
|
g_warning("Field %s: should not be have void type",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_BOOLEAN:
|
|
|
|
G_STRUCT_MEMBER (gboolean, mem, offset) = value->v_boolean != FALSE;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT8:
|
|
|
|
case GI_TYPE_TAG_UINT8:
|
|
|
|
G_STRUCT_MEMBER (guint8, mem, offset) = value->v_uint8;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT16:
|
|
|
|
case GI_TYPE_TAG_UINT16:
|
|
|
|
G_STRUCT_MEMBER (guint16, mem, offset) = value->v_uint16;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT32:
|
|
|
|
case GI_TYPE_TAG_UINT32:
|
2010-10-26 17:12:26 +02:00
|
|
|
case GI_TYPE_TAG_UNICHAR:
|
2010-06-06 18:35:14 +02:00
|
|
|
G_STRUCT_MEMBER (guint32, mem, offset) = value->v_uint32;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT64:
|
|
|
|
case GI_TYPE_TAG_UINT64:
|
|
|
|
G_STRUCT_MEMBER (guint64, mem, offset) = value->v_uint64;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_GTYPE:
|
|
|
|
G_STRUCT_MEMBER (gsize, mem, offset) = value->v_size;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_FLOAT:
|
|
|
|
G_STRUCT_MEMBER (gfloat, mem, offset) = value->v_float;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_DOUBLE:
|
|
|
|
G_STRUCT_MEMBER (gdouble, mem, offset)= value->v_double;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UTF8:
|
|
|
|
case GI_TYPE_TAG_FILENAME:
|
|
|
|
case GI_TYPE_TAG_ARRAY:
|
|
|
|
case GI_TYPE_TAG_GLIST:
|
|
|
|
case GI_TYPE_TAG_GSLIST:
|
|
|
|
case GI_TYPE_TAG_GHASH:
|
|
|
|
g_warning("Field %s: type %s should have is_pointer set",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
|
|
|
gi_type_tag_to_string (gi_type_info_get_tag (type_info)));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_ERROR:
|
|
|
|
/* Needs to be handled by the language binding directly */
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIBaseInfo *interface = gi_type_info_get_interface (type_info);
|
2023-12-12 17:16:30 +01:00
|
|
|
switch (gi_base_info_get_info_type (interface))
|
2010-06-06 18:35:14 +02:00
|
|
|
{
|
|
|
|
case GI_INFO_TYPE_STRUCT:
|
|
|
|
case GI_INFO_TYPE_UNION:
|
|
|
|
case GI_INFO_TYPE_BOXED:
|
|
|
|
/* Needs to be handled by the language binding directly */
|
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_OBJECT:
|
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_ENUM:
|
|
|
|
case GI_INFO_TYPE_FLAGS:
|
2010-06-06 18:15:14 +02:00
|
|
|
{
|
2010-06-06 18:35:14 +02:00
|
|
|
/* See FIXME above
|
|
|
|
*/
|
2023-11-08 15:17:52 +01:00
|
|
|
GITypeTag storage_type = gi_enum_info_get_storage_type ((GIEnumInfo *)interface);
|
2010-06-06 18:35:14 +02:00
|
|
|
switch (storage_type)
|
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_INT8:
|
|
|
|
case GI_TYPE_TAG_UINT8:
|
|
|
|
G_STRUCT_MEMBER (guint8, mem, offset) = (guint8)value->v_int;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT16:
|
|
|
|
case GI_TYPE_TAG_UINT16:
|
|
|
|
G_STRUCT_MEMBER (guint16, mem, offset) = (guint16)value->v_int;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT32:
|
|
|
|
case GI_TYPE_TAG_UINT32:
|
|
|
|
G_STRUCT_MEMBER (guint32, mem, offset) = (guint32)value->v_int;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT64:
|
|
|
|
case GI_TYPE_TAG_UINT64:
|
|
|
|
G_STRUCT_MEMBER (guint64, mem, offset) = (guint64)value->v_int;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_warning("Field %s: Unexpected enum storage type %s",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
|
|
|
gi_type_tag_to_string (storage_type));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_VFUNC:
|
|
|
|
case GI_INFO_TYPE_CALLBACK:
|
|
|
|
g_warning("Field%s: Interface type %d should have is_pointer set",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
2023-12-12 17:16:30 +01:00
|
|
|
gi_base_info_get_info_type (interface));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
|
|
|
case GI_INFO_TYPE_INVALID:
|
|
|
|
case GI_INFO_TYPE_INTERFACE:
|
|
|
|
case GI_INFO_TYPE_FUNCTION:
|
|
|
|
case GI_INFO_TYPE_CONSTANT:
|
2011-05-19 22:12:03 +02:00
|
|
|
case GI_INFO_TYPE_INVALID_0:
|
2010-06-06 18:35:14 +02:00
|
|
|
case GI_INFO_TYPE_VALUE:
|
|
|
|
case GI_INFO_TYPE_SIGNAL:
|
|
|
|
case GI_INFO_TYPE_PROPERTY:
|
|
|
|
case GI_INFO_TYPE_FIELD:
|
|
|
|
case GI_INFO_TYPE_ARG:
|
|
|
|
case GI_INFO_TYPE_TYPE:
|
|
|
|
case GI_INFO_TYPE_UNRESOLVED:
|
|
|
|
g_warning("Field %s: Interface type %d not expected",
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_get_name ((GIBaseInfo *)field_info),
|
2023-12-12 17:16:30 +01:00
|
|
|
gi_base_info_get_info_type (interface));
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
2018-07-29 17:13:16 +02:00
|
|
|
default:
|
|
|
|
break;
|
2010-06-06 18:35:14 +02:00
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_unref ((GIBaseInfo *)interface);
|
2010-06-06 18:15:14 +02:00
|
|
|
break;
|
|
|
|
}
|
2010-06-06 18:35:14 +02:00
|
|
|
break;
|
2018-07-29 17:13:16 +02:00
|
|
|
default:
|
|
|
|
break;
|
2010-06-06 18:35:14 +02:00
|
|
|
}
|
2011-03-14 19:18:22 +01:00
|
|
|
} else {
|
2023-11-08 15:17:52 +01:00
|
|
|
switch (gi_type_info_get_tag (type_info))
|
2011-03-14 19:18:22 +01:00
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIBaseInfo *interface = gi_type_info_get_interface (type_info);
|
2023-12-12 17:16:30 +01:00
|
|
|
switch (gi_base_info_get_info_type (interface))
|
2011-03-14 19:18:22 +01:00
|
|
|
{
|
|
|
|
case GI_INFO_TYPE_OBJECT:
|
|
|
|
case GI_INFO_TYPE_INTERFACE:
|
|
|
|
G_STRUCT_MEMBER (gpointer, mem, offset) = (gpointer)value->v_pointer;
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
2011-05-23 15:59:02 +02:00
|
|
|
default:
|
|
|
|
break;
|
2011-03-14 19:18:22 +01:00
|
|
|
}
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_unref ((GIBaseInfo *)interface);
|
2011-03-14 19:18:22 +01:00
|
|
|
}
|
2023-10-25 19:50:31 +02:00
|
|
|
break;
|
2011-05-23 15:59:02 +02:00
|
|
|
default:
|
|
|
|
break;
|
2011-03-14 19:18:22 +01:00
|
|
|
}
|
2010-06-06 18:35:14 +02:00
|
|
|
}
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
gi_base_info_unref ((GIBaseInfo *)type_info);
|
2010-06-06 18:15:14 +02:00
|
|
|
|
2010-06-06 18:35:14 +02:00
|
|
|
return result;
|
2010-06-06 18:15:14 +02:00
|
|
|
}
|
2023-11-28 18:24:20 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
gi_field_info_class_init (gpointer g_class,
|
|
|
|
gpointer class_data)
|
|
|
|
{
|
|
|
|
GIBaseInfoClass *info_class = g_class;
|
|
|
|
|
|
|
|
info_class->info_type = GI_INFO_TYPE_FIELD;
|
|
|
|
}
|