PyObject * _pygi_marshal_to_py_interface_enum (PyGIInvokeState *state, PyGICallableCache *callable_cache, PyGIArgCache *arg_cache, GIArgument *arg) { PyObject *py_obj = NULL; PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; GIBaseInfo *interface; long c_long; interface = g_type_info_get_interface (arg_cache->type_info); g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM); if (!gi_argument_to_c_long(arg, &c_long, g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { return NULL; } if (iface_cache->g_type == G_TYPE_NONE) { py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long); } else { py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long); } g_base_info_unref (interface); return py_obj; }
static gpointer sv_to_callback (GIArgInfo * arg_info, GITypeInfo * type_info, SV * sv, GPerlI11nInvocationInfo * invocation_info) { GIBaseInfo *callback_interface_info; GPerlI11nPerlCallbackInfo *callback_info; GIScopeType scope; /* the destroy notify func is handled by _handle_automatic_arg */ dwarn (" Perl callback at %d (%s)\n", invocation_info->current_pos, g_base_info_get_name (arg_info)); callback_interface_info = g_type_info_get_interface (type_info); callback_info = create_perl_callback_closure (callback_interface_info, sv); callback_info->data_pos = g_arg_info_get_closure (arg_info); callback_info->destroy_pos = g_arg_info_get_destroy (arg_info); callback_info->free_after_use = FALSE; g_base_info_unref (callback_interface_info); dwarn (" Perl callback data at %d, destroy at %d\n", callback_info->data_pos, callback_info->destroy_pos); scope = (!gperl_sv_is_defined (sv)) ? GI_SCOPE_TYPE_CALL : g_arg_info_get_scope (arg_info); switch (scope) { case GI_SCOPE_TYPE_CALL: dwarn (" Perl callback has scope 'call'\n"); free_after_call (invocation_info, (GFunc) release_perl_callback, callback_info); break; case GI_SCOPE_TYPE_NOTIFIED: dwarn (" Perl callback has scope 'notified'\n"); /* This case is already taken care of by the notify * stuff above */ break; case GI_SCOPE_TYPE_ASYNC: dwarn (" Perl callback has scope 'async'\n"); /* FIXME: callback_info->free_after_use = TRUE; */ break; default: ccroak ("unhandled scope type %d encountered", g_arg_info_get_scope (arg_info)); } invocation_info->callback_infos = g_slist_prepend (invocation_info->callback_infos, callback_info); dwarn (" returning Perl closure %p from info %p\n", callback_info->closure, callback_info); return callback_info->closure; }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback; GIArgInfo *arg_info; GIArgument *callback_argument; arg_info = &(metadata->arg_info); callback = find_callback_function(arg_info); if (!callback) { GITypeInfo type_info; GIBaseInfo *interface_info; VALUE rb_type_name; g_arg_info_load_type(arg_info, &type_info); interface_info = g_type_info_get_interface(&type_info); rb_type_name = CSTR2RVAL(g_base_info_get_name(interface_info)); g_base_info_unref(interface_info); rb_raise(rb_eNotImpError, "TODO: <%s>(%s) callback is not supported yet.", RVAL2CSTR(rb_type_name), g_base_info_get_name(arg_info)); } callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); callback_argument->v_pointer = callback; if (metadata->closure_in_arg_index != -1) { RBGICallbackData *callback_data; GIArgument *closure_argument; callback_data = ALLOC(RBGICallbackData); callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); closure_argument->v_pointer = callback_data; } if (metadata->destroy_in_arg_index != -1) { GIArgument *destroy_argument; destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); destroy_argument->v_pointer = destroy_notify; } }
static void initialize_receiver(VALUE receiver, GITypeInfo *info, GIArgument *value) { GIBaseInfo *interface_info; GIInfoType interface_type; if (g_type_info_get_tag(info) != GI_TYPE_TAG_INTERFACE) { rb_raise(rb_eRuntimeError, "TODO: returned value isn't interface"); } interface_info = g_type_info_get_interface(info); interface_type = g_base_info_get_type(interface_info); g_base_info_unref(interface_info); switch (interface_type) { case GI_INFO_TYPE_OBJECT: G_INITIALIZE(receiver, value->v_pointer); break; case GI_INFO_TYPE_STRUCT: G_INITIALIZE(receiver, value->v_pointer); break; case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: case GI_INFO_TYPE_INVALID_0: rb_raise(rb_eRuntimeError, "TODO: returned value isn't object, struct or union"); break; case GI_INFO_TYPE_UNION: G_INITIALIZE(receiver, value->v_pointer); break; case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_VFUNC: 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: default: rb_raise(rb_eRuntimeError, "TODO: returned value isn't object, struct or union"); break; } }
static PyObject * _pygi_marshal_to_py_interface_flags (PyGIInvokeState *state, PyGICallableCache *callable_cache, PyGIArgCache *arg_cache, GIArgument *arg, gpointer *cleanup_data) { PyObject *py_obj = NULL; PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; GIBaseInfo *interface; long c_long; interface = g_type_info_get_interface (arg_cache->type_info); g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); if (!gi_argument_to_c_long(arg, &c_long, g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { g_base_info_unref (interface); return NULL; } g_base_info_unref (interface); if (iface_cache->g_type == G_TYPE_NONE) { /* An enum with a GType of None is an enum without GType */ PyObject *py_type = pygi_type_import_by_gi_info (iface_cache->interface_info); PyObject *py_args = NULL; if (!py_type) return NULL; py_args = PyTuple_New (1); if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) { Py_DECREF (py_args); Py_DECREF (py_type); return NULL; } py_obj = PyObject_CallFunction (py_type, "l", c_long); Py_DECREF (py_args); Py_DECREF (py_type); } else { py_obj = pyg_flags_from_gtype (iface_cache->g_type, (guint)c_long); } return py_obj; }
static gboolean _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state, PyGICallableCache *callable_cache, PyGIArgCache *arg_cache, PyObject *py_arg, GIArgument *arg, gpointer *cleanup_data) { PyObject *py_long; unsigned long c_ulong; gint is_instance; PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; GIBaseInfo *interface; is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type); py_long = PYGLIB_PyNumber_Long (py_arg); if (py_long == NULL) { PyErr_Clear (); goto err; } c_ulong = PYGLIB_PyLong_AsUnsignedLong (py_long); Py_DECREF (py_long); /* only 0 or argument of type Flag is allowed */ if (!is_instance && c_ulong != 0) goto err; /* Write c_long into arg */ interface = g_type_info_get_interface (arg_cache->type_info); g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); if (!gi_argument_from_c_long(arg, c_ulong, g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { g_base_info_unref (interface); return FALSE; } g_base_info_unref (interface); return TRUE; err: PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s", iface_cache->type_name, Py_TYPE (py_arg)->tp_name); return FALSE; }
/* Retrieves pointer to GIArgument in given array, given that array contains elements of type ti. */ static gssize array_get_elt_size (GITypeInfo *ti) { gssize size = sizeof (gpointer); if (!g_type_info_is_pointer (ti)) { switch (g_type_info_get_tag (ti)) { #define HANDLE_ELT(nameupper, nametype) \ case GI_TYPE_TAG_ ## nameupper: \ return sizeof (nametype); HANDLE_ELT(BOOLEAN, gboolean); HANDLE_ELT(INT8, gint8); HANDLE_ELT(UINT8, guint8); HANDLE_ELT(INT16, gint16); HANDLE_ELT(UINT16, guint16); HANDLE_ELT(INT32, gint32); HANDLE_ELT(UINT32, guint32); HANDLE_ELT(UNICHAR, guint32); HANDLE_ELT(INT64, gint64); HANDLE_ELT(UINT64, guint64); HANDLE_ELT(FLOAT, gfloat); HANDLE_ELT(DOUBLE, gdouble); HANDLE_ELT(GTYPE, GType); #undef HANDLE_ELT case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *info = g_type_info_get_interface (ti); GIInfoType type = g_base_info_get_type (info); if (type == GI_INFO_TYPE_STRUCT) size = g_struct_info_get_size (info); else if (type == GI_INFO_TYPE_UNION) size = g_union_info_get_size (info); g_base_info_unref (info); break; } default: break; } } return size; }
static gboolean source_func_p(GIArgInfo *info) { GITypeInfo type_info; GIBaseInfo *interface_info; GICallableInfo *callback_info; GITypeInfo return_type_info; GIArgInfo first_arg_info; GITypeInfo first_arg_type_info; g_arg_info_load_type(info, &type_info); if (g_type_info_get_tag(&type_info) != GI_TYPE_TAG_INTERFACE) { return FALSE; } interface_info = g_type_info_get_interface(&type_info); if (g_base_info_get_type(interface_info) != GI_INFO_TYPE_CALLBACK) { g_base_info_unref(interface_info); return FALSE; } callback_info = (GICallableInfo *)interface_info; g_callable_info_load_return_type(callback_info, &return_type_info); if (g_type_info_get_tag(&return_type_info) != GI_TYPE_TAG_BOOLEAN) { g_base_info_unref(interface_info); return FALSE; } if (g_callable_info_get_n_args(interface_info) != 1) { g_base_info_unref(interface_info); return FALSE; } g_callable_info_load_arg(interface_info, 0, &first_arg_info); g_arg_info_load_type(&first_arg_info, &first_arg_type_info); if (g_type_info_get_tag(&first_arg_type_info) != GI_TYPE_TAG_VOID) { g_base_info_unref(interface_info); return FALSE; } g_base_info_unref(interface_info); return TRUE; }
static void rb_gi_in_argument_free_interface(GIArgument *argument, GITypeInfo *type_info) { GIBaseInfo *interface_info; GIInfoType interface_type; interface_info = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface_info); if (interface_type == GI_INFO_TYPE_STRUCT) { GType gtype; gtype = g_registered_type_info_get_g_type(interface_info); if (gtype == G_TYPE_VALUE) { GValue *gvalue = argument->v_pointer; g_value_unset(gvalue); xfree(argument->v_pointer); } } g_base_info_unref(interface_info); }
/** * g_type_info_get_ffi_type: * @info: A #GITypeInfo * * Returns: A #ffi_type corresponding to the platform default C ABI for @info. */ ffi_type * g_type_info_get_ffi_type (GITypeInfo *info) { gboolean is_enum = FALSE; GIBaseInfo *iinfo; if (g_type_info_get_tag (info) == GI_TYPE_TAG_INTERFACE) { iinfo = g_type_info_get_interface (info); switch (g_base_info_get_type (iinfo)) { case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: is_enum = TRUE; break; default: break; } g_base_info_unref (iinfo); } return gi_type_tag_get_ffi_type_internal (g_type_info_get_tag (info), g_type_info_is_pointer (info), is_enum); }
void gy_value_init(GValue * val, GITypeInfo * info) { GY_DEBUG("in gy_value_init\n"); GITypeTag type = g_type_info_get_tag(info); GIBaseInfo * itrf; GY_DEBUG("Initializing GValue to %s\n", g_type_tag_to_string(type)); switch (type) { /* basic types */ case GI_TYPE_TAG_BOOLEAN: g_value_init(val, G_TYPE_BOOLEAN); break; case GI_TYPE_TAG_INT8: g_value_init(val, G_TYPE_CHAR); break; case GI_TYPE_TAG_UINT8: g_value_init(val, G_TYPE_UCHAR); break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_INT32: g_value_init(val, G_TYPE_INT); break; case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_UINT32: g_value_init(val, G_TYPE_INT); break; case GI_TYPE_TAG_INT64: g_value_init(val, G_TYPE_INT64); break; case GI_TYPE_TAG_UINT64: g_value_init(val, G_TYPE_UINT64); break; case GI_TYPE_TAG_FLOAT: g_value_init(val, G_TYPE_FLOAT); break; case GI_TYPE_TAG_DOUBLE: g_value_init(val, G_TYPE_DOUBLE); break; case GI_TYPE_TAG_GTYPE: g_value_init(val, G_TYPE_GTYPE); break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: g_value_init(val, G_TYPE_STRING); GY_DEBUG("GValue is string\n"); break; /* interface types */ case GI_TYPE_TAG_INTERFACE: itrf = g_type_info_get_interface(info); switch(g_base_info_get_type (itrf)) { case GI_INFO_TYPE_OBJECT: g_value_init(val, G_TYPE_OBJECT); break; case GI_INFO_TYPE_ENUM: g_value_init(val, g_registered_type_info_get_g_type(itrf)); GY_DEBUG("GValue is enum\n"); break; default: y_errorn("Unimplemented GValue interface type %ld", g_base_info_get_type (itrf)); } g_base_info_unref(itrf); break; case GI_TYPE_TAG_VOID: default: y_error("Unimplement property GValue type"); } GY_DEBUG("out gy_value_init\n"); }
void gy_value_push(GValue * pval, GITypeInfo * info, gy_Object* o) { GITypeTag tag = g_type_info_get_tag(info); GY_DEBUG("Pushing %s from GValue\n", g_type_tag_to_string(tag)); switch (tag) { /* basic types */ case GI_TYPE_TAG_VOID:{ GITypeInfo * cellinfo = g_type_info_get_param_type(info, 0); if (cellinfo) { GITypeTag ctag = g_type_info_get_tag(cellinfo); GY_DEBUG("void contains %s\n", g_type_tag_to_string(ctag)); g_base_info_unref(cellinfo); } ypush_nil(); break;} case GI_TYPE_TAG_BOOLEAN: *ypush_c(NULL) = g_value_get_boolean(pval); break; case GI_TYPE_TAG_INT8: *ypush_gint8(NULL) = g_value_get_schar(pval); break; case GI_TYPE_TAG_UINT8: *ypush_guint8(NULL)= g_value_get_uchar(pval); break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_INT32: *ypush_gint32(NULL) = g_value_get_int(pval); break; case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_UINT32: *ypush_guint32(NULL) = g_value_get_uint(pval); break; case GI_TYPE_TAG_INT64: ypush_long(g_value_get_int64(pval)); break; case GI_TYPE_TAG_UINT64: ypush_long(g_value_get_uint64(pval)); break; case GI_TYPE_TAG_FLOAT: *ypush_f(NULL)=g_value_get_float(pval); break; case GI_TYPE_TAG_DOUBLE: ypush_double(g_value_get_double(pval)); break; case GI_TYPE_TAG_GTYPE: ypush_long(g_value_get_gtype(pval)); break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: *ypush_q(NULL) = p_strcpy(g_value_get_string(pval)); break; /* array types */ case GI_TYPE_TAG_ARRAY: y_error("array"); break; /* interface types */ case GI_TYPE_TAG_INTERFACE: { GIBaseInfo * itrf = g_type_info_get_interface (info); switch(g_base_info_get_type (itrf)) { case GI_INFO_TYPE_ENUM: ypush_long(g_value_get_enum(pval)); g_base_info_unref(itrf); break; case GI_INFO_TYPE_OBJECT: { GObject * prop=g_value_get_object(pval); g_object_ref_sink(prop); if (!prop) { g_base_info_unref(itrf); y_error("get property failed"); } GY_DEBUG("pushing result... "); ypush_check(1); gy_Object * out = ypush_gy_Object(); out->info=itrf; out->object=prop; out->repo=o->repo; } break; default: g_base_info_unref(itrf); y_error ("fix me: only properties of type object supported yet"); } break; } default: y_error("Unimplemented"); } }
/* Marshalls single value from Lua to GLib/C. */ int lgi_marshal_2c (lua_State *L, GITypeInfo *ti, GIArgInfo *ai, GITransfer transfer, gpointer target, int narg, int parent, GICallableInfo *ci, void **args) { int nret = 0; gboolean optional = (parent == LGI_PARENT_CALLER_ALLOC) || (ai == NULL || (g_arg_info_is_optional (ai) || g_arg_info_may_be_null (ai))); GITypeTag tag = g_type_info_get_tag (ti); GIArgument *arg = target; /* Convert narg stack position to absolute one, because during marshalling some temporary items might be pushed to the stack, which would disrupt relative stack addressing of the value. */ lgi_makeabs(L, narg); switch (tag) { case GI_TYPE_TAG_BOOLEAN: { gboolean result; result = lua_toboolean (L, narg) ? TRUE : FALSE; if (parent == LGI_PARENT_FORCE_POINTER) arg->v_pointer = GINT_TO_POINTER (result); else if (parent == LGI_PARENT_IS_RETVAL) { ReturnUnion *ru = (ReturnUnion *) arg; ru->s = result; } else arg->v_boolean = result; break; } case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: { /* Retrieve number from given position. */ lua_Number num = (optional && lua_isnoneornil (L, narg)) ? 0 : luaL_checknumber (L, narg); /* Marshalling float/double into pointer target is not possible. */ g_return_val_if_fail (parent != LGI_PARENT_FORCE_POINTER, 0); /* Store read value into chosen target. */ if (tag == GI_TYPE_TAG_FLOAT) arg->v_float = (float) num; else arg->v_double = (double) num; break; } case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: { gchar *str = NULL; int type = lua_type (L, narg); if (type == LUA_TLIGHTUSERDATA) str = lua_touserdata (L, narg); else if (!optional || (type != LUA_TNIL && type != LUA_TNONE)) { if (type == LUA_TUSERDATA) str = (gchar *) lgi_udata_test (L, narg, LGI_BYTES_BUFFER); if (str == NULL) str = (gchar *) luaL_checkstring (L, narg); } if (tag == GI_TYPE_TAG_FILENAME) { /* Convert from UTF-8 to filename encoding. */ if (str) { str = g_filename_from_utf8 (str, -1, NULL, NULL, NULL); if (transfer != GI_TRANSFER_EVERYTHING) { /* Create temporary object on the stack which will destroy the allocated temporary filename. */ *lgi_guard_create (L, g_free) = (gpointer) str; nret = 1; } } } else if (transfer == GI_TRANSFER_EVERYTHING) str = g_strdup (str); if (parent == LGI_PARENT_FORCE_POINTER) arg->v_pointer = str; else arg->v_string = str; } break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *info = g_type_info_get_interface (ti); GIInfoType type = g_base_info_get_type (info); int info_guard; lgi_gi_info_new (L, info); info_guard = lua_gettop (L); switch (type) { case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: /* If the argument is not numeric, convert to number first. Use enum/flags 'constructor' to do this. */ if (lua_type (L, narg) != LUA_TNUMBER) { lgi_type_get_repotype (L, G_TYPE_INVALID, info); lua_pushvalue (L, narg); lua_call (L, 1, 1); narg = -1; } /* Directly store underlying value. */ marshal_2c_int (L, g_enum_info_get_storage_type (info), arg, narg, optional, parent); /* Remove the temporary value, to keep stack balanced. */ if (narg == -1) lua_pop (L, 1); break; case GI_INFO_TYPE_STRUCT: case GI_INFO_TYPE_UNION: { /* Ideally the g_type_info_is_pointer() should be sufficient here, but there is some gobject-introspection quirk that some struct arguments might not be marked as pointers (e.g. g_variant_equals(), which has ctype of gconstpointer, and thus logic in girparser.c which sets is_pointer attribute fails). Workaround it by checking also argument type - structs as C function arguments are always passed as pointers. */ gboolean by_value = parent != LGI_PARENT_FORCE_POINTER && ((!g_type_info_is_pointer (ti) && ai == NULL) || parent == LGI_PARENT_CALLER_ALLOC); lgi_type_get_repotype (L, G_TYPE_INVALID, info); lgi_record_2c (L, narg, target, by_value, transfer != GI_TRANSFER_NOTHING, optional, FALSE); break; } case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: { arg->v_pointer = lgi_object_2c (L, narg, g_registered_type_info_get_g_type (info), optional, FALSE, transfer != GI_TRANSFER_NOTHING); break; } case GI_INFO_TYPE_CALLBACK: nret = marshal_2c_callable (L, info, ai, &arg->v_pointer, narg, optional, ci, args); break; default: g_assert_not_reached (); } lua_remove (L, info_guard); } break; case GI_TYPE_TAG_ARRAY: { gssize size; GIArrayType atype = g_type_info_get_array_type (ti); nret = marshal_2c_array (L, ti, atype, &arg->v_pointer, &size, narg, optional, transfer); /* Fill in array length argument, if it is specified. */ if (atype == GI_ARRAY_TYPE_C) array_get_or_set_length (ti, NULL, size, ci, args); break; } case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: nret = marshal_2c_list (L, ti, tag, &arg->v_pointer, narg, transfer); break; case GI_TYPE_TAG_GHASH: nret = marshal_2c_hash (L, ti, (GHashTable **) &arg->v_pointer, narg, optional, transfer); break; case GI_TYPE_TAG_VOID: if (g_type_info_is_pointer (ti)) { /* Check and marshal according to real Lua type. */ if (lua_isnoneornil (L, narg)) /* nil -> NULL. */ arg->v_pointer = NULL; if (lua_type (L, narg) == LUA_TSTRING) /* Use string directly. */ arg->v_pointer = (gpointer) lua_tostring (L, narg); else { int type = lua_type (L, narg); if (type == LUA_TLIGHTUSERDATA) /* Generic pointer. */ arg->v_pointer = lua_touserdata (L, narg); else { /* Check memory buffer. */ arg->v_pointer = lgi_udata_test (L, narg, LGI_BYTES_BUFFER); if (!arg->v_pointer) { /* Check object. */ arg->v_pointer = lgi_object_2c (L, narg, G_TYPE_INVALID, FALSE, TRUE, FALSE); if (!arg->v_pointer) { /* Check any kind of record. */ lua_pushnil (L); lgi_record_2c (L, narg, &arg->v_pointer, FALSE, FALSE, FALSE, TRUE); } } } } } break; default: marshal_2c_int (L, tag, arg, narg, optional, parent); } return nret; }
gboolean pygi_g_struct_info_is_simple (GIStructInfo *struct_info) { gboolean is_simple; gsize n_field_infos; gsize i; is_simple = TRUE; n_field_infos = g_struct_info_get_n_fields (struct_info); for (i = 0; i < n_field_infos && is_simple; i++) { GIFieldInfo *field_info; GITypeInfo *field_type_info; GITypeTag field_type_tag; field_info = g_struct_info_get_field (struct_info, i); field_type_info = g_field_info_get_type (field_info); field_type_tag = g_type_info_get_tag (field_type_info); switch (field_type_tag) { case GI_TYPE_TAG_BOOLEAN: case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT64: case GI_TYPE_TAG_UINT64: case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: case GI_TYPE_TAG_UNICHAR: if (g_type_info_is_pointer (field_type_info)) { is_simple = FALSE; } break; case GI_TYPE_TAG_VOID: case GI_TYPE_TAG_GTYPE: case GI_TYPE_TAG_ERROR: 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: is_simple = FALSE; break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *info; GIInfoType info_type; info = g_type_info_get_interface (field_type_info); info_type = g_base_info_get_type (info); switch (info_type) { case GI_INFO_TYPE_STRUCT: if (g_type_info_is_pointer (field_type_info)) { is_simple = FALSE; } else { is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info); } break; case GI_INFO_TYPE_UNION: /* TODO */ is_simple = FALSE; break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: if (g_type_info_is_pointer (field_type_info)) { is_simple = FALSE; } break; case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_INTERFACE: is_simple = FALSE; break; case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: 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: default: g_assert_not_reached(); break; } g_base_info_unref (info); break; } } g_base_info_unref ( (GIBaseInfo *) field_type_info); g_base_info_unref ( (GIBaseInfo *) field_info); } return is_simple; }
gsize _pygi_g_type_info_size (GITypeInfo *type_info) { gsize size = 0; GITypeTag type_tag; type_tag = g_type_info_get_tag (type_info); switch (type_tag) { case GI_TYPE_TAG_BOOLEAN: case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT64: case GI_TYPE_TAG_UINT64: case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: case GI_TYPE_TAG_GTYPE: case GI_TYPE_TAG_UNICHAR: size = _pygi_g_type_tag_size (type_tag); g_assert (size > 0); break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *info; GIInfoType info_type; info = g_type_info_get_interface (type_info); info_type = g_base_info_get_type (info); switch (info_type) { case GI_INFO_TYPE_STRUCT: if (g_type_info_is_pointer (type_info)) { size = sizeof (gpointer); } else { size = g_struct_info_get_size ( (GIStructInfo *) info); } break; case GI_INFO_TYPE_UNION: if (g_type_info_is_pointer (type_info)) { size = sizeof (gpointer); } else { size = g_union_info_get_size ( (GIUnionInfo *) info); } break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: if (g_type_info_is_pointer (type_info)) { size = sizeof (gpointer); } else { GITypeTag type_tag; type_tag = g_enum_info_get_storage_type ( (GIEnumInfo *) info); size = _pygi_g_type_tag_size (type_tag); } break; case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CALLBACK: size = sizeof (gpointer); break; case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: 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: default: g_assert_not_reached(); break; } g_base_info_unref (info); break; } case GI_TYPE_TAG_ARRAY: case GI_TYPE_TAG_VOID: 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: case GI_TYPE_TAG_ERROR: size = sizeof (gpointer); break; } return size; }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback_function; GIArgInfo *arg_info; GIArgument *callback_argument; GIArgument *closure_argument = NULL; GIArgument *destroy_argument = NULL; RBGICallback *callback = NULL; arg_info = &(metadata->arg_info); callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); if (metadata->closure_in_arg_index != -1) { closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); } if (metadata->destroy_in_arg_index != -1) { destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); } if (!rb_block_given_p() && g_arg_info_may_be_null(arg_info)) { callback_argument->v_pointer = NULL; if (closure_argument) { closure_argument->v_pointer = NULL; } if (destroy_argument) { destroy_argument->v_pointer = NULL; } return; } callback_function = find_callback_function(arg_info); if (callback_function) { callback_argument->v_pointer = callback_function; } else { callback = RB_ZALLOC(RBGICallback); callback->type_info = g_arg_info_get_type(arg_info); callback->callback_info = g_type_info_get_interface(callback->type_info); callback->closure = g_callable_info_prepare_closure(callback->callback_info, &(callback->cif), ffi_closure_callback, callback); callback_argument->v_pointer = callback->closure; } if (closure_argument) { RBGICallbackData *callback_data; callback_data = ALLOC(RBGICallbackData); callback_data->callback = callback; callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument->v_pointer = callback_data; } if (destroy_argument) { destroy_argument->v_pointer = destroy_notify; } }
static JSBool boxed_set_field_from_value(JSContext *context, Boxed *priv, GIFieldInfo *field_info, jsval value) { GITypeInfo *type_info; GArgument arg; gboolean success = FALSE; gboolean need_release = FALSE; type_info = g_field_info_get_type (field_info); 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 = set_nested_interface_object (context, 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 (!gjs_value_to_g_argument(context, value, type_info, g_base_info_get_name ((GIBaseInfo *)field_info), GJS_ARGUMENT_FIELD, GI_TRANSFER_NOTHING, TRUE, &arg)) goto out; need_release = TRUE; if (!g_field_info_set_field (field_info, priv->gboxed, &arg)) { gjs_throw(context, "Writing field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); goto out; } success = TRUE; out: if (need_release) gjs_g_argument_release (context, GI_TRANSFER_NOTHING, type_info, &arg); g_base_info_unref ((GIBaseInfo *)type_info); return success; }
/** * g_field_info_set_field: * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union * @value: a #GArgument holding the value to store * * Writes a field identified by a #GFieldInfo to a C structure or * union. 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. * * Returns: %TRUE if writing the field succeeded, otherwise %FALSE */ gboolean g_field_info_set_field (GIFieldInfo *field_info, gpointer mem, const GArgument *value) { int offset; GITypeInfo *type_info; gboolean result = FALSE; if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) return FALSE; offset = g_field_info_get_offset (field_info); type_info = g_field_info_get_type (field_info); if (!g_type_info_is_pointer (type_info)) { switch (g_type_info_get_tag (type_info)) { case GI_TYPE_TAG_VOID: g_warning("Field %s: should not be have void type", g_base_info_get_name ((GIBaseInfo *)field_info)); 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: case GI_TYPE_TAG_SHORT: case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT: case GI_TYPE_TAG_UINT: 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_LONG: case GI_TYPE_TAG_ULONG: G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong; result = TRUE; break; case GI_TYPE_TAG_SSIZE: case GI_TYPE_TAG_SIZE: 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_TIME_T: #if SIZEOF_TIME_T == 4 G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32; #elif SIZEOF_TIME_T == 8 G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64; #else # error "Unexpected size for time_t: not 4 or 8" #endif 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", g_base_info_get_name ((GIBaseInfo *)field_info), g_type_tag_to_string (g_type_info_get_tag (type_info))); break; case GI_TYPE_TAG_ERROR: /* Needs to be handled by the language binding directly */ break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *interface = g_type_info_get_interface (type_info); switch (g_base_info_get_type (interface)) { 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: { /* See FIXME above */ GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); 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: case GI_TYPE_TAG_SHORT: case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT: case GI_TYPE_TAG_UINT: 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; case GI_TYPE_TAG_LONG: case GI_TYPE_TAG_ULONG: G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int; result = TRUE; break; default: g_warning("Field %s: Unexpected enum storage type %s", g_base_info_get_name ((GIBaseInfo *)field_info), g_type_tag_to_string (storage_type)); break; } break; } break; case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_CALLBACK: g_warning("Field%s: Interface type %d should have is_pointer set", g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: case GI_INFO_TYPE_ERROR_DOMAIN: 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", g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; } g_base_info_unref ((GIBaseInfo *)interface); break; } break; } } g_base_info_unref ((GIBaseInfo *)type_info); return result; }
static void argument_from_raw_data_interface(GICallableInfo *callable_info, void *raw_arg, GIArgument *argument, GITypeInfo *type_info) { GIBaseInfo *interface_info; GIInfoType interface_type; interface_info = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface_info); switch (interface_type) { case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: rb_raise(rb_eNotImpError, "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_STRUCT: argument->v_pointer = *((gpointer *)(raw_arg)); break; case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_ENUM: rb_raise(rb_eNotImpError, "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_FLAGS: argument->v_int32= *((gint32 *)(raw_arg)); break; case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: argument->v_pointer = *((gpointer *)(raw_arg)); break; case GI_INFO_TYPE_CONSTANT: rb_raise(rb_eNotImpError, "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_INVALID_0: g_assert_not_reached(); break; case GI_INFO_TYPE_UNION: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_VFUNC: 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: default: rb_raise(rb_eNotImpError, "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; } g_base_info_unref(interface_info); }
/** * g_field_info_get_field: * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union * @value: a #GArgument into which to store the value retrieved * * Reads a field identified by a #GFieldInfo from a C structure or * union. 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. * * Returns: %TRUE if reading the field succeeded, otherwise %FALSE */ gboolean g_field_info_get_field (GIFieldInfo *field_info, gpointer mem, GArgument *value) { int offset; GITypeInfo *type_info; gboolean result = FALSE; if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) return FALSE; offset = g_field_info_get_offset (field_info); type_info = g_field_info_get_type (field_info); if (g_type_info_is_pointer (type_info)) { value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset); result = TRUE; } else { switch (g_type_info_get_tag (type_info)) { case GI_TYPE_TAG_VOID: g_warning("Field %s: should not be have void type", g_base_info_get_name ((GIBaseInfo *)field_info)); 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: case GI_TYPE_TAG_SHORT: case GI_TYPE_TAG_USHORT: value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT: case GI_TYPE_TAG_UINT: 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_LONG: case GI_TYPE_TAG_ULONG: value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset); result = TRUE; break; case GI_TYPE_TAG_SSIZE: case GI_TYPE_TAG_SIZE: 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; case GI_TYPE_TAG_TIME_T: #if SIZEOF_TIME_T == 4 value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset); #elif SIZEOF_TIME_T == 8 value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset); #else # error "Unexpected size for time_t: not 4 or 8" #endif 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", g_base_info_get_name ((GIBaseInfo *)field_info), g_type_tag_to_string (g_type_info_get_tag (type_info))); break; case GI_TYPE_TAG_ERROR: /* Needs to be handled by the language binding directly */ break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *interface = g_type_info_get_interface (type_info); switch (g_base_info_get_type (interface)) { 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: { /* FIXME: there's a mismatch here between the value->v_int we use * here and the glong result returned from g_value_info_get_value(). * But to switch this to glong, we'd have to make g_function_info_invoke() * translate value->v_long to the proper ABI for an enum function * call parameter, which will usually be int, and then fix up language * bindings. */ GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); 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: case GI_TYPE_TAG_SHORT: case GI_TYPE_TAG_USHORT: value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT: case GI_TYPE_TAG_UINT: 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; case GI_TYPE_TAG_LONG: case GI_TYPE_TAG_ULONG: value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset); result = TRUE; break; default: g_warning("Field %s: Unexpected enum storage type %s", g_base_info_get_name ((GIBaseInfo *)field_info), g_type_tag_to_string (storage_type)); break; } break; } case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_CALLBACK: g_warning("Field %s: Interface type %d should have is_pointer set", g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: case GI_INFO_TYPE_ERROR_DOMAIN: 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", g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; } g_base_info_unref ((GIBaseInfo *)interface); break; } break; } } g_base_info_unref ((GIBaseInfo *)type_info); return result; }
static void pygi_signal_closure_marshal(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { PyGILState_STATE state; PyGClosure *pc = (PyGClosure *)closure; PyObject *params, *ret = NULL; guint i; GISignalInfo *signal_info; gint n_sig_info_args; gint sig_info_highest_arg; GSList *list_item = NULL; GSList *pass_by_ref_structs = NULL; state = PyGILState_Ensure(); signal_info = ((PyGISignalClosure *)closure)->signal_info; n_sig_info_args = g_callable_info_get_n_args(signal_info); /* the first argument to a signal callback is instance, but instance is not counted in the introspection data */ sig_info_highest_arg = n_sig_info_args + 1; g_assert_cmpint(sig_info_highest_arg, ==, n_param_values); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); for (i = 0; i < n_param_values; i++) { /* swap in a different initial data for connect_object() */ if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) { g_return_if_fail(pc->swap_data != NULL); Py_INCREF(pc->swap_data); PyTuple_SetItem(params, 0, pc->swap_data); } else if (i == 0) { PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); if (!item) { goto out; } PyTuple_SetItem(params, i, item); } else if (i < sig_info_highest_arg) { GIArgInfo arg_info; GITypeInfo type_info; GITypeTag type_tag; GIArgument arg = { 0, }; PyObject *item = NULL; gboolean free_array = FALSE; gboolean pass_struct_by_ref = FALSE; g_callable_info_load_arg(signal_info, i - 1, &arg_info); g_arg_info_load_type(&arg_info, &type_info); arg = _pygi_argument_from_g_value(¶m_values[i], &type_info); type_tag = g_type_info_get_tag (&type_info); if (type_tag == GI_TYPE_TAG_ARRAY) { /* Skip the self argument of param_values */ arg.v_pointer = _pygi_argument_to_array (&arg, _pygi_argument_array_length_marshal, (void *)(param_values + 1), signal_info, &type_info, &free_array); } /* Hack to ensure struct arguments are passed-by-reference allowing * callback implementors to modify the struct values. This is needed * for keeping backwards compatibility and should be removed in future * versions which support signal output arguments as return values. * See: https://bugzilla.gnome.org/show_bug.cgi?id=735486 * * Note the logic here must match the logic path taken in _pygi_argument_to_object. */ if (type_tag == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *info = g_type_info_get_interface (&type_info); GIInfoType info_type = g_base_info_get_type (info); if (info_type == GI_INFO_TYPE_STRUCT || info_type == GI_INFO_TYPE_BOXED || info_type == GI_INFO_TYPE_UNION) { GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info); gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) && (g_struct_info_is_foreign ((GIStructInfo *) info)); if (!is_foreign && !g_type_is_a (gtype, G_TYPE_VALUE) && g_type_is_a (gtype, G_TYPE_BOXED)) { pass_struct_by_ref = TRUE; } } g_base_info_unref (info); } if (pass_struct_by_ref) { /* transfer everything will ensure the struct is not copied when wrapped. */ item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_EVERYTHING); if (item && PyObject_IsInstance (item, (PyObject *) &PyGIBoxed_Type)) { ((PyGBoxed *)item)->free_on_dealloc = FALSE; pass_by_ref_structs = g_slist_prepend (pass_by_ref_structs, item); } } else { item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_NOTHING); } if (free_array) { g_array_free (arg.v_pointer, FALSE); } if (item == NULL) { PyErr_Print (); goto out; } PyTuple_SetItem(params, i, item); } } /* params passed to function may have extra arguments */ if (pc->extra_args) { PyObject *tuple = params; params = PySequence_Concat(tuple, pc->extra_args); Py_DECREF(tuple); } ret = PyObject_CallObject(pc->callback, params); if (ret == NULL) { if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); goto out; } if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { PyErr_SetString(PyExc_TypeError, "can't convert return value to desired type"); if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); } Py_DECREF(ret); /* Run through the list of structs which have been passed by reference and * check if they are being held longer than the duration of the callback * execution. This is determined if the ref count is greater than 1. * A single ref is held by the argument list and any more would mean the callback * stored a ref somewhere else. In this case we make an internal copy of * the boxed struct so Python can own the memory to it. */ list_item = pass_by_ref_structs; while (list_item) { PyObject *item = list_item->data; if (item->ob_refcnt > 1) { _pygi_boxed_copy_in_place ((PyGIBoxed *)item); } list_item = g_slist_next (list_item); } out: g_slist_free (pass_by_ref_structs); Py_DECREF(params); PyGILState_Release(state); }
static VALUE interface_to_ruby(GIArgument *argument, GITypeInfo *type_info) { VALUE rb_interface; GIBaseInfo *interface_info; GIInfoType interface_type; GType gtype; interface_info = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface_info); gtype = g_registered_type_info_get_g_type(interface_info); switch (interface_type) { case GI_INFO_TYPE_INVALID: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[invalid] -> Ruby"); break; case GI_INFO_TYPE_FUNCTION: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[function] -> Ruby"); break; case GI_INFO_TYPE_CALLBACK: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[callback] -> Ruby"); break; case GI_INFO_TYPE_STRUCT: rb_interface = BOXED2RVAL(argument->v_pointer, gtype); break; case GI_INFO_TYPE_BOXED: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[boxed] -> Ruby"); break; case GI_INFO_TYPE_ENUM: if (gtype == G_TYPE_NONE) { rb_interface = INT2NUM(argument->v_int32); } else { rb_interface = GENUM2RVAL(argument->v_int32, gtype); } break; case GI_INFO_TYPE_FLAGS: if (gtype == G_TYPE_NONE) { rb_interface = INT2NUM(argument->v_int32); } else { rb_interface = GFLAGS2RVAL(argument->v_int32, gtype); } break; case GI_INFO_TYPE_OBJECT: rb_interface = GOBJ2RVAL(argument->v_pointer); break; case GI_INFO_TYPE_INTERFACE: rb_interface = GOBJ2RVAL(argument->v_pointer); break; case GI_INFO_TYPE_CONSTANT: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[constant] -> Ruby"); break; case GI_INFO_TYPE_INVALID_0: g_assert_not_reached(); break; case GI_INFO_TYPE_UNION: rb_interface = BOXED2RVAL(argument->v_pointer, gtype); break; case GI_INFO_TYPE_VALUE: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[value] -> Ruby"); break; case GI_INFO_TYPE_SIGNAL: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[signal] -> Ruby"); break; case GI_INFO_TYPE_VFUNC: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[vfunc] -> Ruby"); break; case GI_INFO_TYPE_PROPERTY: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[property] -> Ruby"); break; case GI_INFO_TYPE_FIELD: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[field] -> Ruby"); break; case GI_INFO_TYPE_ARG: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[arg] -> Ruby"); break; case GI_INFO_TYPE_TYPE: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[type] -> Ruby"); break; case GI_INFO_TYPE_UNRESOLVED: rb_raise(rb_eNotImpError, "TODO: GIArgument(interface)[unresolved] -> Ruby"); break; default: g_assert_not_reached(); break; } g_base_info_unref(interface_info); return rb_interface; }
void gy_value_set_iarg(GValue* pval, GITypeInfo * info, int iarg) { GY_DEBUG("in gy_value_set_iarg\n"); GITypeTag type = g_type_info_get_tag(info); GIBaseInfo * itrf; switch (type) { case GI_TYPE_TAG_BOOLEAN: g_value_set_boolean(pval, ygets_c(iarg)); break; case GI_TYPE_TAG_INT8: g_value_set_schar(pval, ygets_c(iarg)); break; case GI_TYPE_TAG_UINT8: g_value_set_uchar(pval, ygets_c(iarg)); break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_INT32: g_value_set_int(pval, ygets_i(iarg)); break; case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_UINT32: g_value_set_uint(pval, ygets_i(iarg)); break; case GI_TYPE_TAG_INT64: g_value_set_int64(pval, ygets_l(iarg)); break; case GI_TYPE_TAG_UINT64: g_value_set_uint64(pval, ygets_l(iarg)); break; case GI_TYPE_TAG_FLOAT: g_value_set_float(pval, ygets_f(iarg)); break; case GI_TYPE_TAG_DOUBLE: g_value_set_double(pval, ygets_d(iarg)); break; case GI_TYPE_TAG_GTYPE: g_value_set_gtype(pval, ygets_l(iarg)); break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: g_value_set_static_string (pval, ygets_q(iarg)); GY_DEBUG("GValue is string: \"%s\"\n", ygets_q(iarg)); break; /* interface types */ case GI_TYPE_TAG_INTERFACE: itrf = g_type_info_get_interface(info); switch(g_base_info_get_type (itrf)) { case GI_INFO_TYPE_ENUM: g_value_set_enum (pval, ygets_l(iarg)); break; case GI_INFO_TYPE_OBJECT: g_value_set_object(pval, yget_gy_Object(iarg)->object); break; default: y_errorn("Unimplemented GValue interface type %ld", g_base_info_get_type (itrf)); } g_base_info_unref(itrf); break; case GI_TYPE_TAG_VOID: default: y_error("Unimplement property GValue type"); } GY_DEBUG("out gy_iarg2gvalue\n"); }
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; }
static void create_native_closure (GType interface_type, GIInterfaceInfo *iface_info, GIVFuncInfo *vfunc_info, MethodImpl *impl) { GIFunctionInfo *invoker_info; GIStructInfo *struct_info; GIFieldInfo *field_info; GITypeInfo *type_info; GICallbackInfo *callback_info; guint n_fields, i; gboolean found_field_info; invoker_info = g_vfunc_info_get_invoker (vfunc_info); if (invoker_info == NULL) { g_debug ("No invoker for VFunc '%s.%s'", g_base_info_get_name (iface_info), g_base_info_get_name (vfunc_info)); return; } struct_info = g_interface_info_get_iface_struct (iface_info); n_fields = g_struct_info_get_n_fields (struct_info); found_field_info = FALSE; for (i = 0; i < n_fields; i++) { field_info = g_struct_info_get_field (struct_info, i); if (strcmp (g_base_info_get_name (field_info), g_base_info_get_name (vfunc_info)) == 0) { found_field_info = TRUE; break; } g_base_info_unref (field_info); } if (!found_field_info) { g_debug ("No struct field for VFunc '%s.%s'", g_base_info_get_name (iface_info), g_base_info_get_name (vfunc_info)); g_base_info_unref (struct_info); g_base_info_unref (invoker_info); return; } type_info = g_field_info_get_type (field_info); g_assert (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE); callback_info = g_type_info_get_interface (type_info); g_assert (g_base_info_get_type (callback_info) == GI_INFO_TYPE_CALLBACK); impl->interface_type = interface_type; impl->invoker_info = invoker_info; impl->method_name = g_base_info_get_name (invoker_info); impl->closure = g_callable_info_prepare_closure (callback_info, &impl->cif, handle_method_impl, impl); impl->struct_offset = g_field_info_get_offset (field_info); g_base_info_unref (callback_info); g_base_info_unref (type_info); g_base_info_unref (field_info); g_base_info_unref (struct_info); }
static PyObject * _wrap_g_field_info_set_value (PyGIBaseInfo *self, PyObject *args) { PyObject *instance; PyObject *py_value; GIBaseInfo *container_info; GIInfoType container_info_type; gpointer pointer; GITypeInfo *field_type_info; GIArgument value; PyObject *retval = NULL; if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) { 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(); } field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info); /* Check the value. */ { gboolean retval; retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE); if (retval < 0) { goto out; } if (!retval) { _PyGI_ERROR_PREFIX ("argument 2: "); goto out; } } /* Set the field's value. */ /* A few types are not handled by g_field_info_set_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_WRITABLE)) { PyErr_SetString (PyExc_RuntimeError, "field is not writable"); goto out; } info = g_type_info_get_interface (field_type_info); info_type = g_base_info_get_type (info); switch (info_type) { case GI_INFO_TYPE_UNION: PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet"); goto out; case GI_INFO_TYPE_STRUCT: { gboolean is_simple; gsize offset; gssize size; is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info); if (!is_simple) { PyErr_SetString (PyExc_TypeError, "cannot set a structure which has no well-defined ownership transfer rules"); g_base_info_unref (info); goto out; } value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING); if (PyErr_Occurred()) { g_base_info_unref (info); goto out; } offset = g_field_info_get_offset ( (GIFieldInfo *) self->info); size = g_struct_info_get_size ( (GIStructInfo *) info); g_assert (size > 0); g_memmove ((char*) pointer + offset, value.v_pointer, size); g_base_info_unref (info); retval = Py_None; goto out; } default: /* Fallback. */ break; } g_base_info_unref (info); } else if (g_type_info_is_pointer (field_type_info) && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID) { int offset; if (py_value != Py_None && !PYGLIB_PyLong_Check(py_value)) { if (PyErr_WarnEx(PyExc_RuntimeWarning, "Usage of gpointers to store objects is being deprecated. " "Please use integer values only, see: https://bugzilla.gnome.org/show_bug.cgi?id=683599", 1)) goto out; } offset = g_field_info_get_offset ((GIFieldInfo *) self->info); value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING); /* Decrement the previous python object stashed on the void pointer. * This seems somewhat dangerous as the code is blindly assuming any * void pointer field stores a python object pointer and then decrefs it. * This is essentially the same as something like: * Py_XDECREF(struct->void_ptr); */ Py_XDECREF(G_STRUCT_MEMBER (gpointer, pointer, offset)); /* Assign and increment the newly assigned object. At this point the value * arg will hold a pointer the python object "py_value" or NULL. * This is essentially: * struct->void_ptr = value.v_pointer; * Py_XINCREF(struct->void_ptr); */ G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer; Py_XINCREF(G_STRUCT_MEMBER (gpointer, pointer, offset)); retval = Py_None; goto out; } value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING); if (PyErr_Occurred()) { goto out; } if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) { _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN); PyErr_SetString (PyExc_RuntimeError, "unable to set value for field"); goto out; } retval = Py_None; out: g_base_info_unref ( (GIBaseInfo *) field_type_info); Py_XINCREF (retval); return retval; }
static gboolean type_can_be_allocated_directly(GITypeInfo *type_info) { gboolean is_simple = TRUE; if (g_type_info_is_pointer(type_info)) { if (g_type_info_get_tag(type_info) == GI_TYPE_TAG_ARRAY && g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_C) { GITypeInfo *param_info; param_info = g_type_info_get_param_type(type_info, 0); is_simple = type_can_be_allocated_directly(param_info); g_base_info_unref((GIBaseInfo*)param_info); } else { is_simple = FALSE; } } else { switch (g_type_info_get_tag(type_info)) { case GI_TYPE_TAG_BOOLEAN: case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT64: case GI_TYPE_TAG_UINT64: case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: case GI_TYPE_TAG_UNICHAR: break; case GI_TYPE_TAG_VOID: case GI_TYPE_TAG_GTYPE: case GI_TYPE_TAG_ERROR: 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: break; case GI_TYPE_TAG_INTERFACE: { GIBaseInfo *interface = g_type_info_get_interface(type_info); switch (g_base_info_get_type(interface)) { case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_STRUCT: if (!struct_is_simple((GIStructInfo *)interface)) is_simple = FALSE; break; case GI_INFO_TYPE_UNION: /* FIXME: Need to implement */ is_simple = FALSE; break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: break; case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: 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: is_simple = FALSE; break; case GI_INFO_TYPE_INVALID_0: g_assert_not_reached(); break; } g_base_info_unref(interface); break; } } } return is_simple; }
static void rb_gi_argument_from_ruby_interface(GIArgument *argument, GITypeInfo *type_info, VALUE rb_argument) { GIBaseInfo *interface_info; GIInfoType interface_type; GType gtype; interface_info = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface_info); gtype = g_registered_type_info_get_g_type(interface_info); switch (interface_type) { case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: rb_raise(rb_eNotImpError, "TODO: Ruby -> GIArgument(interface)[%s]: <%s>", g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_STRUCT: if (gtype == G_TYPE_VALUE) { GValue *gvalue; gvalue = ALLOC(GValue); memset(gvalue, 0, sizeof(GValue)); if (rb_obj_is_kind_of(rb_argument, rb_cGLibValue)) { GValue *source_gvalue; source_gvalue = RVAL2BOXED(rb_argument, G_TYPE_VALUE); g_value_init(gvalue, source_gvalue->g_type); g_value_copy(source_gvalue, gvalue); } else { rbgobj_initialize_gvalue(gvalue, rb_argument); } argument->v_pointer = gvalue; } else { argument->v_pointer = RVAL2BOXED(rb_argument, gtype); } break; case GI_INFO_TYPE_BOXED: rb_raise(rb_eNotImpError, "TODO: Ruby -> GIArgument(interface)[%s]: <%s>", g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_ENUM: if (gtype == G_TYPE_NONE) { argument->v_int32 = NUM2INT(rb_argument); } else { argument->v_int32 = RVAL2GENUM(rb_argument, gtype); } break; case GI_INFO_TYPE_FLAGS: if (gtype == G_TYPE_NONE) { argument->v_int32 = NUM2INT(rb_argument); } else { argument->v_int32 = RVAL2GFLAGS(rb_argument, gtype); } break; case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: argument->v_pointer = RVAL2GOBJ(rb_argument); break; case GI_INFO_TYPE_CONSTANT: rb_raise(rb_eNotImpError, "TODO: Ruby -> GIArgument(interface)[%s]: <%s>", g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_INVALID_0: g_assert_not_reached(); break; case GI_INFO_TYPE_UNION: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_VFUNC: 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: default: rb_raise(rb_eNotImpError, "TODO: Ruby -> GIArgument(interface)[%s]: <%s>", g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; } g_base_info_unref(interface_info); }
static void out_argument_to_raw_data_interface(GICallableInfo *callable_info, GIArgument *argument, gpointer result, GITypeInfo *type_info, G_GNUC_UNUSED GITransfer transfer /* TODO */, gboolean is_return_value) { GIBaseInfo *interface_info; GIInfoType interface_type; GIFFIReturnValue *ffi_return_value = result; interface_info = g_type_info_get_interface(type_info); interface_type = g_base_info_get_type(interface_info); switch (interface_type) { case GI_INFO_TYPE_INVALID: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_STRUCT: case GI_INFO_TYPE_BOXED: rb_raise(rb_eNotImpError, "TODO: %s::%s: out raw data(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_ENUM: if (is_return_value) { ffi_return_value->v_ulong = argument->v_int; } else { *((gint *)result) = argument->v_int; } break; case GI_INFO_TYPE_FLAGS: case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: rb_raise(rb_eNotImpError, "TODO: %s::%s: out raw data(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; case GI_INFO_TYPE_INVALID_0: g_assert_not_reached(); break; case GI_INFO_TYPE_UNION: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_VFUNC: 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: default: rb_raise(rb_eNotImpError, "TODO: %s::%s: out raw data(interface)[%s]: <%s>", g_base_info_get_namespace(callable_info), g_base_info_get_name(callable_info), g_info_type_to_string(interface_type), g_base_info_get_name(interface_info)); break; } g_base_info_unref(interface_info); }
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; }