VALUE rb_gi_field_info_get_field_raw(GIFieldInfo *info, gpointer memory) { GIArgument argument; GITypeInfo *type_info; GITypeTag type_tag; VALUE rb_field_value; type_info = g_field_info_get_type(info); type_tag = g_type_info_get_tag(type_info); if (!g_field_info_get_field(info, memory, &argument)) { g_base_info_unref(type_info); rb_raise(rb_eArgError, "failed to get field value: %s[%s]", g_base_info_get_name(info), g_type_tag_to_string(type_tag)); } if (type_tag == GI_TYPE_TAG_UTF8) { int offset; offset = g_field_info_get_offset(info); argument.v_string = G_STRUCT_MEMBER(gchar *, memory, offset); }
static JSBool boxed_field_getter (JSContext *context, JSObject *obj, jsid id, jsval *value) { Boxed *priv; GIFieldInfo *field_info; GITypeInfo *type_info; GArgument arg; gboolean success = FALSE; priv = priv_from_js(context, obj); if (!priv) return JS_FALSE; field_info = get_field_info(context, priv, id); if (!field_info) return JS_FALSE; type_info = g_field_info_get_type (field_info); if (priv->gboxed == NULL) { /* direct access to proto field */ gjs_throw(context, "Can't get field %s.%s from a prototype", g_base_info_get_name ((GIBaseInfo *)priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); goto out; } if (!g_type_info_is_pointer (type_info) && g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *interface_info = g_type_info_get_interface(type_info); if (g_base_info_get_type (interface_info) == GI_INFO_TYPE_STRUCT || g_base_info_get_type (interface_info) == GI_INFO_TYPE_BOXED) { success = get_nested_interface_object (context, obj, priv, field_info, type_info, interface_info, value); g_base_info_unref ((GIBaseInfo *)interface_info); goto out; } g_base_info_unref ((GIBaseInfo *)interface_info); } if (!g_field_info_get_field (field_info, priv->gboxed, &arg)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); goto out; } if (!gjs_value_from_g_argument (context, value, type_info, &arg, TRUE)) goto out; success = TRUE; out: g_base_info_unref ((GIBaseInfo *)field_info); g_base_info_unref ((GIBaseInfo *)type_info); return success; }
static PyObject * _wrap_g_field_info_get_value (PyGIBaseInfo *self, PyObject *args) { PyObject *instance; GIBaseInfo *container_info; GIInfoType container_info_type; gpointer pointer; GITypeInfo *field_type_info; GIArgument value; PyObject *py_value = NULL; gboolean free_array = FALSE; memset(&value, 0, sizeof(GIArgument)); if (!PyArg_ParseTuple (args, "O:FieldInfo.get_value", &instance)) { return NULL; } container_info = g_base_info_get_container (self->info); g_assert (container_info != NULL); /* Check the instance. */ if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) { _PyGI_ERROR_PREFIX ("argument 1: "); return NULL; } /* Get the pointer to the container. */ container_info_type = g_base_info_get_type (container_info); switch (container_info_type) { case GI_INFO_TYPE_UNION: case GI_INFO_TYPE_STRUCT: pointer = pyg_boxed_get (instance, void); break; case GI_INFO_TYPE_OBJECT: pointer = pygobject_get (instance); break; default: /* Other types don't have fields. */ g_assert_not_reached(); } /* Get the field's value. */ field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info); /* A few types are not handled by g_field_info_get_field, so do it here. */ if (!g_type_info_is_pointer (field_type_info) && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *info; GIInfoType info_type; if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_READABLE)) { PyErr_SetString (PyExc_RuntimeError, "field is not readable"); goto out; } info = g_type_info_get_interface (field_type_info); info_type = g_base_info_get_type (info); g_base_info_unref (info); switch (info_type) { case GI_INFO_TYPE_UNION: PyErr_SetString (PyExc_NotImplementedError, "getting an union is not supported yet"); goto out; case GI_INFO_TYPE_STRUCT: { gsize offset; offset = g_field_info_get_offset ( (GIFieldInfo *) self->info); value.v_pointer = (char*) pointer + offset; goto argument_to_object; } default: /* Fallback. */ break; } } if (!g_field_info_get_field ( (GIFieldInfo *) self->info, pointer, &value)) { PyErr_SetString (PyExc_RuntimeError, "unable to get the value"); goto out; } if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) { value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL, field_type_info, &free_array); } argument_to_object: py_value = _pygi_argument_to_object (&value, field_type_info, GI_TRANSFER_NOTHING); if (free_array) { g_array_free (value.v_pointer, FALSE); } out: g_base_info_unref ( (GIBaseInfo *) field_type_info); return py_value; }
/* a hook on getting a property; set value_p to override property's value. * Return value is JS_FALSE on OOM/exception. */ static JSBool param_get_prop(JSContext *context, JSObject *obj, jsid id, jsval *value_p) { JSBool success; Param *priv; GParamSpec *pspec; char *name; GType gtype; GIObjectInfo *info = NULL, *parent_info = NULL; GIFieldInfo *field_info = NULL; GITypeInfo *type_info = NULL; GIArgument arg; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not something we affect, but no error */ priv = priv_from_js(context, obj); if (priv == NULL) { g_free(name); return JS_FALSE; /* wrong class */ } success = JS_FALSE; pspec = priv->gparam; gtype = G_TYPE_FROM_INSTANCE(pspec); info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), gtype); if (info == NULL) { /* We may have a non-introspectable GParamSpec subclass here. Just return VOID. */ *value_p = JSVAL_VOID; success = JS_TRUE; goto out; } parent_info = g_object_info_get_parent(info); field_info = find_field_info(info, name); if (field_info == NULL) { /* Try it on the parent GParamSpec for generic GParamSpec properties. */ field_info = find_field_info(parent_info, name); } if (field_info == NULL) { *value_p = JSVAL_VOID; success = JS_TRUE; goto out; } type_info = g_field_info_get_type(field_info); if (!g_field_info_get_field(field_info, priv->gparam, &arg)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name(info), g_base_info_get_name((GIBaseInfo*)field_info)); goto out; } if (!gjs_value_from_g_argument(context, value_p, type_info, &arg, TRUE)) goto out; success = JS_TRUE; out: if (field_info != NULL) g_base_info_unref((GIBaseInfo*)field_info); if (type_info != NULL) g_base_info_unref((GIBaseInfo*)type_info); if (info != NULL) g_base_info_unref((GIBaseInfo*)info); if (parent_info != NULL) g_base_info_unref((GIBaseInfo*)parent_info); g_free(name); return success; }