Example #1
0
static VALUE
array_to_ruby(gpointer array, GITypeInfo *type_info)
{
    VALUE rb_array;
    GIArrayType array_type;
    gint n_elements;

    array_type = g_type_info_get_array_type(type_info);
    n_elements = g_type_info_get_array_length(type_info);
    if (n_elements == -1) {
        rb_array = rb_ary_new();
    } else {
        rb_array = rb_ary_new2(n_elements);
    }
    switch (array_type) {
      case GI_ARRAY_TYPE_C:
        array_c_to_ruby(array, type_info, rb_array);
        break;
      case GI_ARRAY_TYPE_ARRAY:
        rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[array] -> Ruby");
        break;
      case GI_ARRAY_TYPE_PTR_ARRAY:
        rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[ptr-array] -> Ruby");
        break;
      case GI_ARRAY_TYPE_BYTE_ARRAY:
        rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[byte-array] -> Ruby");
        break;
      default:
        g_assert_not_reached();
        break;
    }

    return rb_array;
}
Example #2
0
static void
array_c_to_ruby(const gchar **elements, GITypeInfo *type_info, VALUE rb_array)
{
    gint n_elements;
    gboolean fixed_size_p;
    gboolean zero_terminated_p;

    n_elements = g_type_info_get_array_length(type_info);
    fixed_size_p = g_type_info_get_array_fixed_size(type_info);
    zero_terminated_p = g_type_info_is_zero_terminated(type_info);
    if (n_elements != -1) {
        gint i;
        for (i = 0; i < n_elements; i++) {
            rb_ary_push(rb_array, CSTR2RVAL(elements[i]));
        }
    } else if (zero_terminated_p) {
        for (; *elements; elements++) {
            rb_ary_push(rb_array, CSTR2RVAL(*elements));
        }
    } else {
        rb_raise(rb_eNotImpError,
                 "TODO: GIArgument(array)[c] -> Ruby: "
                 "zero-terminated: %s "
                 "fixed-size: %s "
                 "length: %d",
                 zero_terminated_p ? "true" : "false",
                 fixed_size_p ? "true" : "false",
                 n_elements);
    }
}
Example #3
0
File: marshal.c Project: ntd/lgi
/* Gets or sets the length of the array. */
static void
array_get_or_set_length (GITypeInfo *ti, gssize *get_length, gssize set_length,
			 GICallableInfo *ci, void **args)
{
  gint param = g_type_info_get_array_length (ti);
  if (param >= 0 && ci != NULL && param < g_callable_info_get_n_args (ci))
    {
      GIArgInfo ai;
      GITypeInfo eti;
      GIArgument *val;
      g_callable_info_load_arg (ci, param, &ai);
      g_arg_info_load_type (&ai, &eti);
      if (g_arg_info_get_direction (&ai) == GI_DIRECTION_IN)
	/* For input parameters, value is directly pointed do by args
	   table element. */
	val = (GIArgument *) args[param];
      else
	/* For output arguments, args table element points to pointer
	   to value. */
	val = *(GIArgument **) args[param];

      switch (g_type_info_get_tag (&eti))
	{
#define HANDLE_ELT(tag, field)			\
	  case GI_TYPE_TAG_ ## tag:		\
	    if (get_length != NULL)		\
	      *get_length = val->v_ ## field;	\
	    else				\
	      val->v_ ## field = set_length;	\
	  break

	  HANDLE_ELT(INT8, int8);
	  HANDLE_ELT(UINT8, uint8);
	  HANDLE_ELT(INT16, int16);
	  HANDLE_ELT(UINT16, uint16);
	  HANDLE_ELT(INT32, int32);
	  HANDLE_ELT(UINT32, uint32);
	  HANDLE_ELT(INT64, int64);
	  HANDLE_ELT(UINT64, uint64);
#undef HANDLE_ELT

	default:
	  g_assert_not_reached ();
	}
    }
}
Example #4
0
static void
fill_metadata_array_from_callable_info(GPtrArray *args_metadata,
                                       GICallableInfo *info)
{
    GITypeInfo return_type_info;
    RBGIArgMetadata *array_length_metadata;
    gint array_length_index = -1;

    g_callable_info_load_return_type(info, &return_type_info);
    if (g_type_info_get_tag(&return_type_info) != GI_TYPE_TAG_ARRAY) {
        return;
    }

    array_length_index = g_type_info_get_array_length(&return_type_info);
    if (array_length_index == -1) {
        return;
    }

    array_length_metadata = g_ptr_array_index(args_metadata, array_length_index);
    array_length_metadata->array_length_p = TRUE;
    array_length_metadata->rb_arg_index = -1;
}
Example #5
0
static void
fill_metadata_array(GPtrArray *args_metadata)
{
    guint i;

    for (i = 0; i < args_metadata->len; i++) {
        RBGIArgMetadata *metadata;
        RBGIArgMetadata *array_length_metadata;
        GIArgInfo *arg_info;
        GITypeInfo type_info;
        gint array_length_index = -1;

        metadata = g_ptr_array_index(args_metadata, i);
        arg_info = &(metadata->arg_info);

        g_arg_info_load_type(arg_info, &type_info);
        if (g_type_info_get_tag(&type_info) != GI_TYPE_TAG_ARRAY) {
            continue;
        }
        metadata->array_p = TRUE;

        array_length_index = g_type_info_get_array_length(&type_info);
        if (array_length_index == -1) {
            continue;
        }

        array_length_metadata = g_ptr_array_index(args_metadata,
                                                  array_length_index);
        array_length_metadata->array_length_p = TRUE;
        array_length_metadata->rb_arg_index = -1;
        array_length_metadata->array_in_arg_index =
            metadata->in_arg_index;
        metadata->array_length_in_arg_index =
            array_length_metadata->in_arg_index;
        metadata->array_length_arg_index = array_length_index;
    }
}
Example #6
0
/**
 * _pygi_argument_to_array
 * @arg: The argument to convert
 * @array_length_policy: Closure for marshalling the array length argument when needed.
 * @user_data1: Generic user data passed to the array_length_policy.
 * @user_data2: Generic user data passed to the array_length_policy.
 * @type_info: The type info for @arg
 * @out_free_array: A return location for a gboolean that indicates whether
 *                  or not the wrapped GArray should be freed
 *
 * Make sure an array type argument is wrapped in a GArray.
 *
 * Note: This method can *not* be folded into _pygi_argument_to_object() because
 * arrays are special in the sense that they might require access to @args in
 * order to get the length.
 *
 * Returns: A GArray wrapping @arg. If @out_free_array has been set to TRUE then
 *          free the array with g_array_free() without freeing the data members.
 *          Otherwise don't free the array.
 */
GArray *
_pygi_argument_to_array (GIArgument  *arg,
                         PyGIArgArrayLengthPolicy array_length_policy,
                         void        *user_data1,
                         void        *user_data2,
                         GITypeInfo  *type_info,
                         gboolean    *out_free_array)
{
    GITypeInfo *item_type_info;
    gboolean is_zero_terminated;
    gsize item_size;
    gssize length;
    GArray *g_array;
    
    g_return_val_if_fail (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ARRAY, NULL);

    if (arg->v_pointer == NULL) {
        return NULL;
    }
    
    switch (g_type_info_get_array_type (type_info)) {
        case GI_ARRAY_TYPE_C:
            is_zero_terminated = g_type_info_is_zero_terminated (type_info);
            item_type_info = g_type_info_get_param_type (type_info, 0);

            item_size = _pygi_g_type_info_size (item_type_info);

            g_base_info_unref ( (GIBaseInfo *) item_type_info);

            if (is_zero_terminated) {
                length = g_strv_length (arg->v_pointer);
            } else {
                length = g_type_info_get_array_fixed_size (type_info);
                if (length < 0) {
                    gint length_arg_pos;

                    if (G_UNLIKELY (array_length_policy == NULL)) {
                        g_critical ("Unable to determine array length for %p",
                                    arg->v_pointer);
                        g_array = g_array_new (is_zero_terminated, FALSE, item_size);
                        *out_free_array = TRUE;
                        return g_array;
                    }

                    length_arg_pos = g_type_info_get_array_length (type_info);
                    g_assert (length_arg_pos >= 0);

                    length = array_length_policy (length_arg_pos, user_data1, user_data2);
                    if (length < 0) {
                        return NULL;
                    }
                }
            }

            g_assert (length >= 0);

            g_array = g_array_new (is_zero_terminated, FALSE, item_size);

            g_free (g_array->data);
            g_array->data = arg->v_pointer;
            g_array->len = length;
            *out_free_array = TRUE;
            break;
        case GI_ARRAY_TYPE_ARRAY:
        case GI_ARRAY_TYPE_BYTE_ARRAY:
            /* Note: GByteArray is really just a GArray */
            g_array = arg->v_pointer;
            *out_free_array = FALSE;
            break;
        case GI_ARRAY_TYPE_PTR_ARRAY:
        {
            GPtrArray *ptr_array = (GPtrArray*) arg->v_pointer;
            g_array = g_array_sized_new (FALSE, FALSE,
                                         sizeof(gpointer),
                                         ptr_array->len);
             g_array->data = (char*) ptr_array->pdata;
             g_array->len = ptr_array->len;
             *out_free_array = TRUE;
             break;
        }
        default:
            g_critical ("Unexpected array type %u",
                        g_type_info_get_array_type (type_info));
            g_array = NULL;
            break;
    }

    return g_array;
}