Exemplo n.º 1
0
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;
}
Exemplo n.º 3
0
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;
    }
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;

}
Exemplo n.º 7
0
Arquivo: marshal.c Projeto: ntd/lgi
/* 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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 11
0
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");
}
Exemplo n.º 12
0
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");
  }


}
Exemplo n.º 13
0
Arquivo: marshal.c Projeto: ntd/lgi
/* 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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
    }
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
/**
 * 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;
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
0
/**
 * 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;
}
Exemplo n.º 21
0
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(&param_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(&param_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);
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
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");
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
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);
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
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);
}
Exemplo n.º 30
0
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;
}