/* Creates marshaller closure for specified fundamental object type. If specified object does not have custom setvalue/getvalue functions registered, returns nil. Signature is: marshaller = marshal.fundamental(gtype) */ static int marshal_fundamental (lua_State *L) { /* Find associated baseinfo. */ GIBaseInfo *info = g_irepository_find_by_gtype (NULL, lgi_type_get_gtype (L, 1)); if (info) { lgi_gi_info_new (L, info); if (GI_IS_OBJECT_INFO (info) && g_object_info_get_fundamental (info)) { GIObjectInfoGetValueFunction get_value = lgi_object_get_function_ptr (info, g_object_info_get_get_value_function); GIObjectInfoSetValueFunction set_value = lgi_object_get_function_ptr (info, g_object_info_get_set_value_function); if (get_value && set_value) { lua_pushlightuserdata (L, get_value); lua_pushlightuserdata (L, set_value); lua_pushcclosure (L, marshal_fundamental_marshaller, 2); return 1; } } } lua_pushnil (L); return 1; }
/* Converts either GType or gi.info into repotype table. */ static int core_repotype (lua_State *L) { GType gtype = G_TYPE_INVALID; GIBaseInfo **info = lgi_udata_test (L, 1, LGI_GI_INFO); if (!info) gtype = lgi_type_get_gtype (L, 1); lgi_type_get_repotype (L, gtype, info ? *info : NULL); return 1; }
GType lgi_type_get_gtype (lua_State *L, int narg) { /* Handle simple cases natively, forward to Lua implementation for the rest. */ switch (lua_type (L, narg)) { case LUA_TNIL: case LUA_TNONE: return G_TYPE_INVALID; case LUA_TNUMBER: return lua_tonumber (L, narg); case LUA_TLIGHTUSERDATA: return (GType) lua_touserdata (L, narg); case LUA_TSTRING: return g_type_from_name (lua_tostring (L, narg)); case LUA_TTABLE: { GType gtype; lgi_makeabs (L, narg); lua_pushstring (L, "_gtype"); lua_rawget (L, narg); gtype = lgi_type_get_gtype (L, -1); lua_pop (L, 1); return gtype; } default: return luaL_error (L, "GType expected, got %s", lua_typename (L, lua_type (L, narg))); } }
/* Converts any allowed GType kind to lightuserdata form. */ static int core_gtype (lua_State *L) { lua_pushlightuserdata (L, (gpointer) lgi_type_get_gtype (L, 1)); return 1; }
/* Marshals integral types to C. If requested, makes sure that the value is actually marshalled into val->v_pointer no matter what the input type is. */ static void marshal_2c_int (lua_State *L, GITypeTag tag, GIArgument *val, int narg, gboolean optional, int parent) { (void) optional; switch (tag) { #define HANDLE_INT(nameup, namelow, ptrconv, pct, val_min, val_max, ut) \ case GI_TYPE_TAG_ ## nameup: \ val->v_ ## namelow = check_number (L, narg, val_min, val_max); \ if (parent == LGI_PARENT_FORCE_POINTER) \ val->v_pointer = \ G ## ptrconv ## _TO_POINTER ((pct) val->v_ ## namelow); \ else if (sizeof (g ## namelow) <= sizeof (long) \ && parent == LGI_PARENT_IS_RETVAL) \ { \ ReturnUnion *ru = (ReturnUnion *) val; \ ru->ut = ru->arg.v_ ## namelow; \ } \ break #define HANDLE_INT_NOPTR(nameup, namelow, val_min, val_max, ut) \ case GI_TYPE_TAG_ ## nameup: \ val->v_ ## namelow = check_number (L, narg, val_min, val_max); \ g_assert (parent != LGI_PARENT_FORCE_POINTER); \ if (sizeof (g ## namelow) <= sizeof (long) \ && parent == LGI_PARENT_IS_RETVAL) \ { \ ReturnUnion *ru = (ReturnUnion *) val; \ ru->ut = ru->arg.v_ ## namelow; \ } \ break HANDLE_INT(INT8, int8, INT, gint, -0x80, 0x7f, s); HANDLE_INT(UINT8, uint8, UINT, guint, 0, 0xff, u); HANDLE_INT(INT16, int16, INT, gint, -0x8000, 0x7fff, s); HANDLE_INT(UINT16, uint16, UINT, guint, 0, 0xffff, u); HANDLE_INT(INT32, int32, INT, gint, -0x80000000LL, 0x7fffffffLL, s); HANDLE_INT(UINT32, uint32, UINT, guint, 0, 0xffffffffUL, u); HANDLE_INT(UNICHAR, uint32, UINT, guint, 0, 0x7fffffffLL, u); HANDLE_INT_NOPTR(INT64, int64, ((lua_Number) -0x7f00000000000000LL) - 1, 0x7fffffffffffffffLL, s); HANDLE_INT_NOPTR(UINT64, uint64, 0, 0xffffffffffffffffULL, u); #undef HANDLE_INT #undef HANDLE_INT_NOPTR case GI_TYPE_TAG_GTYPE: { #if GLIB_SIZEOF_SIZE_T == 4 val->v_uint32 = #else val->v_uint64 = #endif lgi_type_get_gtype (L, narg); break; } default: g_assert_not_reached (); } }