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; }
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); } }
/* 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 (); } } }
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; }
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; } }
/** * _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; }