gobject-introspection 3.4.9 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2021 Ruby-GNOME Project Team
3
+ * Copyright (C) 2012-2022 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -20,12 +20,6 @@
20
20
 
21
21
  #include "rb-gi-private.h"
22
22
 
23
- static gboolean
24
- rb_gi_arg_info_may_be_null(GIArgInfo *arg_info)
25
- {
26
- return g_arg_info_may_be_null(arg_info);
27
- }
28
-
29
23
  static gboolean
30
24
  rb_gi_is_registered_type(GIInfoType type)
31
25
  {
@@ -79,38 +73,30 @@ rb_gi_arg_metadata_type_clear(RBGIArgMetadataType *type)
79
73
  }
80
74
  }
81
75
 
82
- static RBGIArgMetadata *
83
- rb_gi_arg_metadata_new(GICallableInfo *callable_info, gint i)
76
+ void
77
+ rb_gi_arg_metadata_init_type_info(RBGIArgMetadata *metadata,
78
+ GITypeInfo *type_info)
84
79
  {
85
- RBGIArgMetadata *metadata;
86
- GIArgInfo *arg_info;
87
- GITypeInfo *type_info;
88
-
89
- metadata = ALLOC(RBGIArgMetadata);
90
- metadata->callable_info = callable_info;
91
- arg_info = &(metadata->arg_info);
92
- g_callable_info_load_arg(callable_info, i, arg_info);
93
- metadata->name = g_base_info_get_name(arg_info);
94
- type_info = g_arg_info_get_type(arg_info);
80
+ metadata->type_info = type_info;
95
81
  rb_gi_arg_metadata_type_init(&(metadata->type), type_info);
96
82
  rb_gi_arg_metadata_type_init(&(metadata->element_type), NULL);
97
83
  rb_gi_arg_metadata_type_init(&(metadata->key_type), NULL);
98
84
  rb_gi_arg_metadata_type_init(&(metadata->value_type), NULL);
99
- metadata->scope_type = g_arg_info_get_scope(arg_info);
100
- metadata->direction = g_arg_info_get_direction(arg_info);
101
- metadata->transfer = g_arg_info_get_ownership_transfer(arg_info);
85
+ metadata->scope_type = GI_SCOPE_TYPE_INVALID;
86
+ metadata->direction = GI_DIRECTION_IN;
87
+ metadata->transfer = GI_TRANSFER_NOTHING;
102
88
  metadata->array_type = GI_ARRAY_TYPE_C;
103
- metadata->callback_p = (metadata->scope_type != GI_SCOPE_TYPE_INVALID);
89
+ metadata->callback_p = FALSE;
104
90
  metadata->closure_p = FALSE;
105
91
  metadata->destroy_p = FALSE;
106
92
  metadata->interface_p = (metadata->type.tag == GI_TYPE_TAG_INTERFACE);
107
93
  metadata->array_p = (metadata->type.tag == GI_TYPE_TAG_ARRAY);
108
94
  metadata->array_length_p = FALSE;
109
- metadata->may_be_null_p = rb_gi_arg_info_may_be_null(arg_info);
110
- metadata->caller_allocates_p = g_arg_info_is_caller_allocates(arg_info);
95
+ metadata->may_be_null_p = FALSE;
96
+ metadata->caller_allocates_p = FALSE;
111
97
  metadata->zero_terminated_p = FALSE;
112
- metadata->output_buffer_p = rb_gi_arg_info_is_output_buffer(arg_info);
113
- metadata->index = i;
98
+ metadata->input_buffer_p = FALSE;
99
+ metadata->output_buffer_p = FALSE;
114
100
  metadata->in_arg_index = -1;
115
101
  metadata->closure_in_arg_index = -1;
116
102
  metadata->destroy_in_arg_index = -1;
@@ -147,26 +133,59 @@ rb_gi_arg_metadata_new(GICallableInfo *callable_info, gint i)
147
133
  default:
148
134
  break;
149
135
  }
136
+ }
137
+
138
+ static RBGIArgMetadata *
139
+ rb_gi_arg_metadata_new(GICallableInfo *callable_info, gint i)
140
+ {
141
+
142
+ RBGIArgMetadata *metadata = ALLOC(RBGIArgMetadata);
143
+ metadata->callable_info = callable_info;
144
+ GIArgInfo *arg_info = &(metadata->arg_info);
145
+ g_callable_info_load_arg(callable_info, i, arg_info);
146
+ metadata->name = g_base_info_get_name(arg_info);
147
+ metadata->index = i;
148
+
149
+ rb_gi_arg_metadata_init_type_info(metadata,
150
+ g_arg_info_get_type(arg_info));
151
+
152
+ metadata->scope_type = g_arg_info_get_scope(arg_info);
153
+ metadata->direction = g_arg_info_get_direction(arg_info);
154
+ metadata->transfer = g_arg_info_get_ownership_transfer(arg_info);
155
+ metadata->callback_p = (metadata->scope_type != GI_SCOPE_TYPE_INVALID);
156
+ metadata->may_be_null_p = g_arg_info_may_be_null(arg_info);
157
+ metadata->caller_allocates_p = g_arg_info_is_caller_allocates(arg_info);
158
+ metadata->input_buffer_p = rb_gi_arg_info_is_input_buffer(arg_info);
159
+ metadata->output_buffer_p = rb_gi_arg_info_is_output_buffer(arg_info);
150
160
 
151
161
  return metadata;
152
162
  }
153
163
 
154
- static void
155
- rb_gi_arg_metadata_free(RBGIArgMetadata *metadata)
164
+ void
165
+ rb_gi_arg_metadata_clear(RBGIArgMetadata *metadata)
156
166
  {
157
167
  rb_gi_arg_metadata_type_clear(&(metadata->value_type));
158
168
  rb_gi_arg_metadata_type_clear(&(metadata->key_type));
159
169
  rb_gi_arg_metadata_type_clear(&(metadata->element_type));
160
170
  rb_gi_arg_metadata_type_clear(&(metadata->type));
171
+ }
172
+
173
+ void
174
+ rb_gi_arg_metadata_free(RBGIArgMetadata *metadata)
175
+ {
176
+ rb_gi_arg_metadata_clear(metadata);
161
177
  xfree(metadata);
162
178
  }
163
179
 
164
180
  static void
165
181
  rb_gi_arguments_allocate(RBGIArguments *args)
166
182
  {
167
- gint i, n_args;
183
+ if (!args->info) {
184
+ return;
185
+ }
168
186
 
169
- n_args = g_callable_info_get_n_args(args->info);
187
+ gint n_args = g_callable_info_get_n_args(args->info);
188
+ gint i;
170
189
  for (i = 0; i < n_args; i++) {
171
190
  GIArgument argument = {0};
172
191
  RBGIArgMetadata *metadata;
@@ -345,6 +364,10 @@ rb_gi_arguments_fill_metadata_rb_arg_index(RBGIArguments *args)
345
364
  static void
346
365
  rb_gi_arguments_fill_metadata(RBGIArguments *args)
347
366
  {
367
+ if (!args->metadata) {
368
+ return;
369
+ }
370
+
348
371
  rb_gi_arguments_fill_metadata_callback(args);
349
372
  rb_gi_arguments_fill_metadata_array(args);
350
373
  rb_gi_arguments_fill_metadata_array_from_callable_info(args);
@@ -419,20 +442,31 @@ rb_gi_arguments_init(RBGIArguments *args,
419
442
  void **raw_args)
420
443
  {
421
444
  args->info = info;
422
- args->namespace = g_base_info_get_namespace(info);
423
- if (GI_IS_FUNCTION_INFO(info)) {
424
- args->name = g_function_info_get_symbol((GIFunctionInfo *)info);
445
+ if (info) {
446
+ args->namespace = g_base_info_get_namespace(info);
447
+ if (GI_IS_FUNCTION_INFO(info)) {
448
+ args->name = g_function_info_get_symbol((GIFunctionInfo *)info);
449
+ } else {
450
+ args->name = g_base_info_get_name(info);
451
+ }
425
452
  } else {
426
- args->name = g_base_info_get_name(info);
453
+ args->namespace = NULL;
454
+ args->name = NULL;
427
455
  }
428
456
  args->rb_receiver = rb_receiver;
429
457
  args->receiver_type_class = NULL;
430
458
  args->rb_args = rb_args;
431
459
  args->raw_args = raw_args;
432
- args->in_args = g_array_new(FALSE, FALSE, sizeof(GIArgument));
433
- args->out_args = g_array_new(FALSE, FALSE, sizeof(GIArgument));
434
- args->metadata =
435
- g_ptr_array_new_with_free_func(rb_gi_arguments_metadata_free);
460
+ if (NIL_P(rb_args) && !raw_args) {
461
+ args->in_args = NULL;
462
+ args->out_args = NULL;
463
+ args->metadata = NULL;
464
+ } else {
465
+ args->in_args = g_array_new(FALSE, FALSE, sizeof(GIArgument));
466
+ args->out_args = g_array_new(FALSE, FALSE, sizeof(GIArgument));
467
+ args->metadata =
468
+ g_ptr_array_new_with_free_func(rb_gi_arguments_metadata_free);
469
+ }
436
470
  args->rb_mode_p = !(NIL_P(rb_args));
437
471
 
438
472
  if (!NIL_P(rb_receiver)) {
@@ -457,9 +491,9 @@ rb_gi_arguments_init(RBGIArguments *args,
457
491
 
458
492
  rb_gi_arguments_allocate(args);
459
493
  rb_gi_arguments_fill_metadata(args);
460
- if (args->rb_mode_p) {
494
+ if (!NIL_P(rb_args)) {
461
495
  rb_gi_arguments_fill_rb_args(args);
462
- } else {
496
+ } else if (raw_args) {
463
497
  rb_gi_arguments_fill_raw_args(args);
464
498
  }
465
499
  }
@@ -473,22 +507,21 @@ rb_gi_arguments_clear(RBGIArguments *args)
473
507
  if (args->receiver_type_class) {
474
508
  g_type_class_unref(args->receiver_type_class);
475
509
  }
476
- g_array_unref(args->in_args);
477
- g_array_unref(args->out_args);
478
- g_ptr_array_unref(args->metadata);
510
+ if (args->in_args) {
511
+ g_array_unref(args->in_args);
512
+ }
513
+ if (args->out_args) {
514
+ g_array_unref(args->out_args);
515
+ }
516
+ if (args->metadata) {
517
+ g_ptr_array_unref(args->metadata);
518
+ }
479
519
  }
480
520
 
481
521
  VALUE
482
- rb_gi_arguments_get_rb_return_value(RBGIArguments *args,
483
- GIArgument *return_value)
522
+ rb_gi_arguments_get_rb_in_args(RBGIArguments *args)
484
523
  {
485
- /* TODO */
486
- VALUE rb_return_value = GI_RETURN_ARGUMENT2RVAL(args->info,
487
- return_value,
488
- args->in_args,
489
- args->out_args,
490
- args->metadata);
491
- return rb_return_value;
524
+ return rb_gi_arguments_in_to_ruby(args);
492
525
  }
493
526
 
494
527
  VALUE
@@ -497,67 +530,1984 @@ rb_gi_arguments_get_rb_out_args(RBGIArguments *args)
497
530
  return rb_gi_arguments_out_to_ruby(args);
498
531
  }
499
532
 
500
- void
501
- rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
502
- VALUE rb_error)
533
+ typedef struct {
534
+ RBGIArguments *args;
535
+ GIArgument *arg;
536
+ RBGIArgMetadata *arg_metadata;
537
+ gboolean duplicate;
538
+ GIInterfaceInfo *interface_info;
539
+ } InterfaceToRubyData;
540
+
541
+ static VALUE
542
+ rb_gi_arguments_convert_arg_interface_body(VALUE user_data)
503
543
  {
504
- if (!g_callable_info_can_throw_gerror(args->info)) {
505
- return;
544
+ InterfaceToRubyData *data = (InterfaceToRubyData *)user_data;
545
+ GIInfoType interface_type = g_base_info_get_type(data->interface_info);
546
+ GType gtype = g_registered_type_info_get_g_type(data->interface_info);
547
+ switch (interface_type) {
548
+ case GI_INFO_TYPE_INVALID:
549
+ case GI_INFO_TYPE_FUNCTION:
550
+ case GI_INFO_TYPE_CALLBACK:
551
+ rb_raise(rb_eNotImpError,
552
+ "TODO: GIArgument(interface)[%s] -> Ruby",
553
+ g_info_type_to_string(interface_type));
554
+ return Qnil;
555
+ case GI_INFO_TYPE_STRUCT:
556
+ return rb_gi_struct_info_to_ruby(data->interface_info,
557
+ data->arg->v_pointer,
558
+ !data->duplicate);
559
+ case GI_INFO_TYPE_BOXED:
560
+ rb_raise(rb_eNotImpError,
561
+ "TODO: GIArgument(interface)[%s] -> Ruby",
562
+ g_info_type_to_string(interface_type));
563
+ return Qnil;
564
+ case GI_INFO_TYPE_ENUM:
565
+ if (gtype == G_TYPE_NONE) {
566
+ return INT2NUM(data->arg->v_int32);
567
+ } else {
568
+ return GENUM2RVAL(data->arg->v_int32, gtype);
569
+ }
570
+ case GI_INFO_TYPE_FLAGS:
571
+ if (gtype == G_TYPE_NONE) {
572
+ return INT2NUM(data->arg->v_int32);
573
+ } else {
574
+ return GFLAGS2RVAL(data->arg->v_int32, gtype);
575
+ }
576
+ case GI_INFO_TYPE_OBJECT:
577
+ case GI_INFO_TYPE_INTERFACE:
578
+ return GOBJ2RVAL(data->arg->v_pointer);
579
+ case GI_INFO_TYPE_CONSTANT:
580
+ rb_raise(rb_eNotImpError,
581
+ "TODO: GIArgument(interface)[%s] -> Ruby",
582
+ g_info_type_to_string(interface_type));
583
+ return Qnil;
584
+ case GI_INFO_TYPE_INVALID_0:
585
+ g_assert_not_reached();
586
+ return Qnil;
587
+ case GI_INFO_TYPE_UNION:
588
+ return BOXED2RVAL(data->arg->v_pointer, gtype);
589
+ case GI_INFO_TYPE_VALUE:
590
+ case GI_INFO_TYPE_SIGNAL:
591
+ case GI_INFO_TYPE_VFUNC:
592
+ case GI_INFO_TYPE_PROPERTY:
593
+ case GI_INFO_TYPE_FIELD:
594
+ case GI_INFO_TYPE_ARG:
595
+ case GI_INFO_TYPE_TYPE:
596
+ case GI_INFO_TYPE_UNRESOLVED:
597
+ rb_raise(rb_eNotImpError,
598
+ "TODO: GIArgument(interface)[%s] -> Ruby",
599
+ g_info_type_to_string(interface_type));
600
+ return Qnil;
601
+ default:
602
+ g_assert_not_reached();
603
+ return Qnil;
506
604
  }
605
+ }
507
606
 
508
- gint n_args = g_callable_info_get_n_args(args->info);
509
- /* GError ** isn't listed in args. */
510
- GError **gerror = *((gpointer *)(args->raw_args[n_args]));
511
- VALUE cGLibErrorInfo = rb_const_get(mGLib, rb_intern("ErrorInfo"));
512
- if (NIL_P(rb_error)) {
513
- g_set_error(gerror,
514
- RBG_RUBY_ERROR,
515
- RBG_RUBY_ERROR_UNKNOWN,
516
- "Unknown error");
517
- } else {
518
- VALUE message = rb_funcall(rb_error, rb_intern("message"), 0);
519
- VALUE backtrace = rb_funcall(rb_error, rb_intern("backtrace"), 0);
520
- VALUE formatted_backtrace =
521
- rb_ary_join(backtrace, rb_str_new_cstr(" \n"));
522
- GQuark gdomain = RBG_RUBY_ERROR;
523
- gint gcode = RBG_RUBY_ERROR_UNKNOWN;
524
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_error, cGLibErrorInfo))) {
525
- VALUE domain = rb_funcall(rb_error, rb_intern("domain"), 0);
526
- VALUE code = rb_funcall(rb_error, rb_intern("code"), 0);
527
- if (!NIL_P(domain) && !NIL_P(code)) {
528
- gdomain = g_quark_from_string(RVAL2CSTR(domain));
529
- gcode = NUM2INT(code);
607
+ static VALUE
608
+ rb_gi_arguments_convert_arg_interface_ensure(VALUE user_data)
609
+ {
610
+ InterfaceToRubyData *data = (InterfaceToRubyData *)user_data;
611
+
612
+ if (data->interface_info) {
613
+ g_base_info_unref(data->interface_info);
614
+ }
615
+
616
+ return Qnil;
617
+ }
618
+
619
+ static VALUE
620
+ rb_gi_arguments_convert_arg_interface(RBGIArguments *args,
621
+ GIArgument *arg,
622
+ RBGIArgMetadata *arg_metadata,
623
+ gboolean duplicate)
624
+ {
625
+ InterfaceToRubyData data;
626
+ data.args = args;
627
+ data.arg = arg;
628
+ data.arg_metadata = arg_metadata;
629
+ data.duplicate = duplicate;
630
+ data.interface_info = g_type_info_get_interface(arg_metadata->type_info);
631
+ return rb_ensure(rb_gi_arguments_convert_arg_interface_body, (VALUE)&data,
632
+ rb_gi_arguments_convert_arg_interface_ensure, (VALUE)&data);
633
+ }
634
+
635
+ typedef struct {
636
+ RBGIArguments *args;
637
+ GIArgument *arg;
638
+ RBGIArgMetadata *arg_metadata;
639
+ GITypeInfo *element_type_info;
640
+ GITypeTag element_type_tag;
641
+ GITypeInfo *interface_type_info;
642
+ } ArrayLikeToRubyData;
643
+
644
+ static VALUE
645
+ rb_gi_arguments_convert_arg_array_like_ensure(VALUE user_data)
646
+ {
647
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
648
+
649
+ if (data->element_type_info) {
650
+ g_base_info_unref(data->element_type_info);
651
+ }
652
+ if (data->interface_type_info) {
653
+ g_base_info_unref(data->interface_type_info);
654
+ }
655
+
656
+ return Qnil;
657
+ }
658
+
659
+ static VALUE
660
+ rb_gi_arguments_convert_arg_array_body_c_sized_interface(
661
+ ArrayLikeToRubyData *data,
662
+ gint64 length,
663
+ const char *array_c_type)
664
+ {
665
+ gconstpointer *elements = data->arg->v_pointer;
666
+ data->interface_type_info =
667
+ g_type_info_get_interface(data->element_type_info);
668
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
669
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
670
+ switch (type) {
671
+ case GI_INFO_TYPE_INVALID:
672
+ case GI_INFO_TYPE_FUNCTION:
673
+ case GI_INFO_TYPE_CALLBACK:
674
+ rb_raise(rb_eNotImpError,
675
+ "TODO: GIArgument(array)[c][%s][interface(%s)](%s) -> Ruby",
676
+ array_c_type,
677
+ g_info_type_to_string(type),
678
+ g_type_name(gtype));
679
+ return Qnil;
680
+ case GI_INFO_TYPE_STRUCT:
681
+ if (gtype == G_TYPE_NONE) {
682
+ VALUE rb_arg = rb_ary_new_capa(length);
683
+ gint64 i;
684
+ for (i = 0; i < length; i++) {
685
+ rb_ary_push(rb_arg,
686
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
687
+ (gpointer)elements[i],
688
+ TRUE));
689
+ }
690
+ return rb_arg;
691
+ } else {
692
+ /* TODO: Should we check caller_allocates? */
693
+ gsize struct_size =
694
+ g_struct_info_get_size(data->interface_type_info);
695
+ VALUE rb_arg = rb_ary_new_capa(length);
696
+ gint64 i;
697
+ for (i = 0; i < length; i++) {
698
+ gpointer element = ((gchar *)elements) + struct_size * i;
699
+ rb_ary_push(rb_arg, BOXED2RVAL(element, gtype));
530
700
  }
701
+ return rb_arg;
531
702
  }
532
- g_set_error(gerror,
533
- gdomain,
534
- gcode,
535
- "%s\n %s\n",
536
- RVAL2CSTR(message),
537
- RVAL2CSTR(formatted_backtrace));
703
+ case GI_INFO_TYPE_BOXED:
704
+ case GI_INFO_TYPE_ENUM:
705
+ case GI_INFO_TYPE_FLAGS:
706
+ rb_raise(rb_eNotImpError,
707
+ "TODO: GIArgument(array)[c][%s][interface(%s)](%s) -> Ruby",
708
+ array_c_type,
709
+ g_info_type_to_string(type),
710
+ g_type_name(gtype));
711
+ return Qnil;
712
+ case GI_INFO_TYPE_OBJECT:
713
+ {
714
+ VALUE rb_arg = rb_ary_new_capa(length);
715
+ gint64 i;
716
+ for (i = 0; i < length; i++) {
717
+ rb_ary_push(rb_arg, GOBJ2RVAL((GObject *)(elements[i])));
718
+ }
719
+ return rb_arg;
720
+ }
721
+ case GI_INFO_TYPE_INTERFACE:
722
+ case GI_INFO_TYPE_CONSTANT:
723
+ case GI_INFO_TYPE_INVALID_0:
724
+ case GI_INFO_TYPE_UNION:
725
+ case GI_INFO_TYPE_VALUE:
726
+ case GI_INFO_TYPE_SIGNAL:
727
+ case GI_INFO_TYPE_VFUNC:
728
+ case GI_INFO_TYPE_PROPERTY:
729
+ case GI_INFO_TYPE_FIELD:
730
+ case GI_INFO_TYPE_ARG:
731
+ case GI_INFO_TYPE_TYPE:
732
+ case GI_INFO_TYPE_UNRESOLVED:
733
+ rb_raise(rb_eNotImpError,
734
+ "TODO: GIArgument(array)[c][%s][interface(%s)](%s) -> Ruby",
735
+ array_c_type,
736
+ g_info_type_to_string(type),
737
+ g_type_name(gtype));
738
+ return Qnil;
739
+ default:
740
+ g_assert_not_reached();
741
+ return Qnil;
538
742
  }
539
743
  }
540
744
 
541
- static void
542
- rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
543
- VALUE rb_result,
544
- gpointer raw_result,
545
- GITypeInfo *type_info,
546
- GITransfer transfer,
547
- gboolean is_return_value)
745
+ static VALUE
746
+ rb_gi_arguments_convert_arg_array_body_c_sized(ArrayLikeToRubyData *data,
747
+ gint64 length)
548
748
  {
549
- GIBaseInfo *interface_info;
550
- GIInfoType interface_type;
551
- GIFFIReturnValue *ffi_return_value = raw_result;
552
-
553
- interface_info = g_type_info_get_interface(type_info);
554
- interface_type = g_base_info_get_type(interface_info);
749
+ const char *array_c_type = "length";
750
+ gconstpointer elements = data->arg->v_pointer;
751
+ switch (data->element_type_tag) {
752
+ case GI_TYPE_TAG_VOID:
753
+ rb_raise(rb_eNotImpError,
754
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
755
+ array_c_type,
756
+ g_type_tag_to_string(data->element_type_tag));
757
+ return Qnil;
758
+ case GI_TYPE_TAG_BOOLEAN:
759
+ {
760
+ const gboolean *booleans = (const gboolean *)elements;
761
+ VALUE rb_arg = rb_ary_new_capa(length);
762
+ gint64 i;
763
+ for (i = 0; i < length; i++) {
764
+ rb_ary_push(rb_arg, CBOOL2RVAL(booleans[i]));
765
+ }
766
+ return rb_arg;
767
+ }
768
+ case GI_TYPE_TAG_INT8:
769
+ {
770
+ const gint8 *numbers = (const gint8 *)elements;
771
+ VALUE rb_arg = rb_ary_new_capa(length);
772
+ gint64 i;
773
+ for (i = 0; i < length; i++) {
774
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
775
+ }
776
+ return rb_arg;
777
+ }
778
+ case GI_TYPE_TAG_UINT8:
779
+ if (data->arg_metadata->input_buffer_p) {
780
+ VALUE rb_arg = rb_str_new_static(elements, length);
781
+ rb_str_freeze(rb_arg);
782
+ return rb_arg;
783
+ } else {
784
+ const guint8 *numbers = (const guint8 *)elements;
785
+ VALUE rb_arg = rb_ary_new_capa(length);
786
+ gint64 i;
787
+ for (i = 0; i < length; i++) {
788
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
789
+ }
790
+ return rb_arg;
791
+ }
792
+ case GI_TYPE_TAG_INT16:
793
+ {
794
+ const gint16 *numbers = (const gint16 *)elements;
795
+ VALUE rb_arg = rb_ary_new_capa(length);
796
+ gint64 i;
797
+ for (i = 0; i < length; i++) {
798
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
799
+ }
800
+ return rb_arg;
801
+ }
802
+ case GI_TYPE_TAG_UINT16:
803
+ {
804
+ const guint16 *numbers = (const guint16 *)elements;
805
+ VALUE rb_arg = rb_ary_new_capa(length);
806
+ gint64 i;
807
+ for (i = 0; i < length; i++) {
808
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
809
+ }
810
+ return rb_arg;
811
+ }
812
+ case GI_TYPE_TAG_INT32:
813
+ {
814
+ const gint32 *numbers = (const gint32 *)elements;
815
+ VALUE rb_arg = rb_ary_new_capa(length);
816
+ gint64 i;
817
+ for (i = 0; i < length; i++) {
818
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
819
+ }
820
+ return rb_arg;
821
+ }
822
+ case GI_TYPE_TAG_UINT32:
823
+ {
824
+ const guint32 *numbers = (const guint32 *)elements;
825
+ VALUE rb_arg = rb_ary_new_capa(length);
826
+ gint64 i;
827
+ for (i = 0; i < length; i++) {
828
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
829
+ }
830
+ return rb_arg;
831
+ }
832
+ case GI_TYPE_TAG_INT64:
833
+ {
834
+ const gint64 *numbers = (const gint64 *)elements;
835
+ VALUE rb_arg = rb_ary_new_capa(length);
836
+ gint64 i;
837
+ for (i = 0; i < length; i++) {
838
+ rb_ary_push(rb_arg, LL2NUM(numbers[i]));
839
+ }
840
+ return rb_arg;
841
+ }
842
+ case GI_TYPE_TAG_UINT64:
843
+ {
844
+ const guint64 *numbers = (const guint64 *)elements;
845
+ VALUE rb_arg = rb_ary_new_capa(length);
846
+ gint64 i;
847
+ for (i = 0; i < length; i++) {
848
+ rb_ary_push(rb_arg, ULL2NUM(numbers[i]));
849
+ }
850
+ return rb_arg;
851
+ }
852
+ case GI_TYPE_TAG_FLOAT:
853
+ {
854
+ const gfloat *numbers = (const gfloat *)elements;
855
+ VALUE rb_arg = rb_ary_new_capa(length);
856
+ gint64 i;
857
+ for (i = 0; i < length; i++) {
858
+ rb_ary_push(rb_arg, rb_float_new(numbers[i]));
859
+ }
860
+ return rb_arg;
861
+ }
862
+ case GI_TYPE_TAG_DOUBLE:
863
+ {
864
+ const gdouble *numbers = (const gdouble *)elements;
865
+ VALUE rb_arg = rb_ary_new_capa(length);
866
+ gint64 i;
867
+ for (i = 0; i < length; i++) {
868
+ rb_ary_push(rb_arg, rb_float_new(numbers[i]));
869
+ }
870
+ return rb_arg;
871
+ }
872
+ case GI_TYPE_TAG_GTYPE:
873
+ rb_raise(rb_eNotImpError,
874
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
875
+ array_c_type,
876
+ g_type_tag_to_string(data->element_type_tag));
877
+ return Qnil;
878
+ case GI_TYPE_TAG_UTF8:
879
+ {
880
+ const gchar **strings = (const gchar **)elements;
881
+ VALUE rb_arg = rb_ary_new_capa(length);
882
+ gint64 i;
883
+ for (i = 0; i < length; i++) {
884
+ rb_ary_push(rb_arg, CSTR2RVAL(strings[i]));
885
+ }
886
+ return rb_arg;
887
+ }
888
+ case GI_TYPE_TAG_FILENAME:
889
+ {
890
+ const gchar **filenames = (const gchar **)elements;
891
+ VALUE rb_arg = rb_ary_new_capa(length);
892
+ gint64 i;
893
+ for (i = 0; i < length; i++) {
894
+ rb_ary_push(rb_arg, CSTRFILENAME2RVAL(filenames[i]));
895
+ }
896
+ return rb_arg;
897
+ }
898
+ case GI_TYPE_TAG_ARRAY:
899
+ rb_raise(rb_eNotImpError,
900
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
901
+ array_c_type,
902
+ g_type_tag_to_string(data->element_type_tag));
903
+ return Qnil;
904
+ case GI_TYPE_TAG_INTERFACE:
905
+ return rb_gi_arguments_convert_arg_array_body_c_sized_interface(
906
+ data, length, array_c_type);
907
+ case GI_TYPE_TAG_GLIST:
908
+ case GI_TYPE_TAG_GSLIST:
909
+ case GI_TYPE_TAG_GHASH:
910
+ case GI_TYPE_TAG_ERROR:
911
+ case GI_TYPE_TAG_UNICHAR:
912
+ rb_raise(rb_eNotImpError,
913
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
914
+ array_c_type,
915
+ g_type_tag_to_string(data->element_type_tag));
916
+ return Qnil;
917
+ default:
918
+ g_assert_not_reached();
919
+ return Qnil;
920
+ }
921
+ }
555
922
 
556
- switch (interface_type) {
557
- case GI_INFO_TYPE_INVALID:
558
- case GI_INFO_TYPE_FUNCTION:
559
- case GI_INFO_TYPE_CALLBACK:
560
- case GI_INFO_TYPE_STRUCT:
923
+ static VALUE
924
+ rb_gi_arguments_convert_arg_array_body_c_fixed_size(ArrayLikeToRubyData *data,
925
+ gint fixed_size)
926
+ {
927
+ const char *array_c_type = "[fixed-size]";
928
+ switch (data->element_type_tag) {
929
+ case GI_TYPE_TAG_VOID:
930
+ case GI_TYPE_TAG_BOOLEAN:
931
+ case GI_TYPE_TAG_INT8:
932
+ case GI_TYPE_TAG_UINT8:
933
+ case GI_TYPE_TAG_INT16:
934
+ case GI_TYPE_TAG_UINT16:
935
+ case GI_TYPE_TAG_INT32:
936
+ case GI_TYPE_TAG_UINT32:
937
+ case GI_TYPE_TAG_INT64:
938
+ case GI_TYPE_TAG_UINT64:
939
+ case GI_TYPE_TAG_FLOAT:
940
+ case GI_TYPE_TAG_DOUBLE:
941
+ case GI_TYPE_TAG_GTYPE:
942
+ rb_raise(rb_eNotImpError,
943
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
944
+ array_c_type,
945
+ g_type_tag_to_string(data->element_type_tag));
946
+ return Qnil;
947
+ case GI_TYPE_TAG_UTF8:
948
+ case GI_TYPE_TAG_FILENAME:
949
+ case GI_TYPE_TAG_ARRAY:
950
+ rb_raise(rb_eNotImpError,
951
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
952
+ array_c_type,
953
+ g_type_tag_to_string(data->element_type_tag));
954
+ return Qnil;
955
+ case GI_TYPE_TAG_INTERFACE:
956
+ return rb_gi_arguments_convert_arg_array_body_c_sized_interface(
957
+ data, fixed_size, array_c_type);
958
+ case GI_TYPE_TAG_GLIST:
959
+ case GI_TYPE_TAG_GSLIST:
960
+ case GI_TYPE_TAG_GHASH:
961
+ case GI_TYPE_TAG_ERROR:
962
+ case GI_TYPE_TAG_UNICHAR:
963
+ rb_raise(rb_eNotImpError,
964
+ "TODO: GIArgument(array)[c][%s][%s] -> Ruby",
965
+ array_c_type,
966
+ g_type_tag_to_string(data->element_type_tag));
967
+ return Qnil;
968
+ default:
969
+ g_assert_not_reached();
970
+ return Qnil;
971
+ }
972
+ }
973
+
974
+ static VALUE
975
+ rb_gi_arguments_convert_arg_array_body_c(ArrayLikeToRubyData *data,
976
+ gint64 length)
977
+ {
978
+ gconstpointer *elements = data->arg->v_pointer;
979
+ if (!elements) {
980
+ return rb_ary_new();
981
+ }
982
+
983
+ GITypeInfo *type_info = data->arg_metadata->type_info;
984
+ gint fixed_size = g_type_info_get_array_fixed_size(type_info);
985
+ gboolean zero_terminated_p = g_type_info_is_zero_terminated(type_info);
986
+
987
+ if (length != -1) {
988
+ return rb_gi_arguments_convert_arg_array_body_c_sized(data, length);
989
+ } else if (zero_terminated_p) {
990
+ return STRV2RVAL((const gchar **)elements);
991
+ } else if (fixed_size != -1) {
992
+ return rb_gi_arguments_convert_arg_array_body_c_fixed_size(data,
993
+ fixed_size);
994
+ } else {
995
+ rb_raise(rb_eNotImpError,
996
+ "TODO: GIArgument(array)[c] -> Ruby: "
997
+ "zero-terminated: %s "
998
+ "fixed-size: %d "
999
+ "length: %" G_GINT64_FORMAT,
1000
+ zero_terminated_p ? "true" : "false",
1001
+ fixed_size,
1002
+ length);
1003
+ return Qnil;
1004
+ }
1005
+ }
1006
+
1007
+ static VALUE
1008
+ rb_gi_arguments_convert_arg_array_body_array_interface(ArrayLikeToRubyData *data)
1009
+ {
1010
+ GArray *elements = data->arg->v_pointer;
1011
+ data->interface_type_info =
1012
+ g_type_info_get_interface(data->element_type_info);
1013
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
1014
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
1015
+ switch (type) {
1016
+ case GI_INFO_TYPE_INVALID:
1017
+ case GI_INFO_TYPE_FUNCTION:
1018
+ case GI_INFO_TYPE_CALLBACK:
1019
+ rb_raise(rb_eNotImpError,
1020
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
1021
+ g_info_type_to_string(type),
1022
+ g_type_name(gtype));
1023
+ return Qnil;
1024
+ case GI_INFO_TYPE_STRUCT:
1025
+ if (gtype == G_TYPE_NONE) {
1026
+ VALUE rb_arg = rb_ary_new_capa(elements->len);
1027
+ guint element_size = g_array_get_element_size(elements);
1028
+ guint i;
1029
+ for (i = 0; i < elements->len; i++) {
1030
+ gpointer element;
1031
+ element = elements->data + (element_size * i);
1032
+ rb_ary_push(rb_arg,
1033
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
1034
+ element,
1035
+ FALSE));
1036
+ }
1037
+ return rb_arg;
1038
+ } else {
1039
+ rb_raise(rb_eNotImpError,
1040
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
1041
+ g_info_type_to_string(type),
1042
+ g_type_name(gtype));
1043
+ return Qnil;
1044
+ }
1045
+ case GI_INFO_TYPE_BOXED:
1046
+ case GI_INFO_TYPE_ENUM:
1047
+ case GI_INFO_TYPE_FLAGS:
1048
+ case GI_INFO_TYPE_OBJECT:
1049
+ case GI_INFO_TYPE_INTERFACE:
1050
+ case GI_INFO_TYPE_CONSTANT:
1051
+ case GI_INFO_TYPE_INVALID_0:
1052
+ case GI_INFO_TYPE_UNION:
1053
+ case GI_INFO_TYPE_VALUE:
1054
+ case GI_INFO_TYPE_SIGNAL:
1055
+ case GI_INFO_TYPE_VFUNC:
1056
+ case GI_INFO_TYPE_PROPERTY:
1057
+ case GI_INFO_TYPE_FIELD:
1058
+ case GI_INFO_TYPE_ARG:
1059
+ case GI_INFO_TYPE_TYPE:
1060
+ case GI_INFO_TYPE_UNRESOLVED:
1061
+ rb_raise(rb_eNotImpError,
1062
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
1063
+ g_info_type_to_string(type),
1064
+ g_type_name(gtype));
1065
+ return Qnil;
1066
+ default:
1067
+ g_assert_not_reached();
1068
+ return Qnil;
1069
+ }
1070
+ }
1071
+
1072
+ static VALUE
1073
+ rb_gi_arguments_convert_arg_array_body_array(ArrayLikeToRubyData *data)
1074
+ {
1075
+ GArray *elements = data->arg->v_pointer;
1076
+ if (!elements) {
1077
+ return Qnil;
1078
+ }
1079
+
1080
+ switch (data->element_type_tag) {
1081
+ case GI_TYPE_TAG_VOID:
1082
+ case GI_TYPE_TAG_BOOLEAN:
1083
+ case GI_TYPE_TAG_INT8:
1084
+ case GI_TYPE_TAG_UINT8:
1085
+ case GI_TYPE_TAG_INT16:
1086
+ case GI_TYPE_TAG_UINT16:
1087
+ case GI_TYPE_TAG_INT32:
1088
+ case GI_TYPE_TAG_UINT32:
1089
+ case GI_TYPE_TAG_INT64:
1090
+ case GI_TYPE_TAG_UINT64:
1091
+ case GI_TYPE_TAG_FLOAT:
1092
+ case GI_TYPE_TAG_DOUBLE:
1093
+ case GI_TYPE_TAG_GTYPE:
1094
+ case GI_TYPE_TAG_UTF8:
1095
+ case GI_TYPE_TAG_FILENAME:
1096
+ case GI_TYPE_TAG_ARRAY:
1097
+ rb_raise(rb_eNotImpError,
1098
+ "TODO: GIArgument(array)[array][%s] -> Ruby",
1099
+ g_type_tag_to_string(data->element_type_tag));
1100
+ return Qnil;
1101
+ case GI_TYPE_TAG_INTERFACE:
1102
+ return rb_gi_arguments_convert_arg_array_body_array_interface(data);
1103
+ case GI_TYPE_TAG_GLIST:
1104
+ case GI_TYPE_TAG_GSLIST:
1105
+ case GI_TYPE_TAG_GHASH:
1106
+ case GI_TYPE_TAG_ERROR:
1107
+ case GI_TYPE_TAG_UNICHAR:
1108
+ rb_raise(rb_eNotImpError,
1109
+ "TODO: GIArgument(array)[array][%s] -> Ruby",
1110
+ g_type_tag_to_string(data->element_type_tag));
1111
+ return Qnil;
1112
+ default:
1113
+ g_assert_not_reached();
1114
+ return Qnil;
1115
+ }
1116
+ }
1117
+
1118
+ static gint64
1119
+ rb_gi_arguments_convert_arg_array_body_extract_length(GIArgument *arg,
1120
+ RBGIArgMetadata *metadata,
1121
+ gboolean is_pointer)
1122
+ {
1123
+ switch (metadata->type.tag) {
1124
+ case GI_TYPE_TAG_VOID:
1125
+ case GI_TYPE_TAG_BOOLEAN:
1126
+ rb_raise(rb_eNotImpError,
1127
+ "TODO: invalid out array length argument?: <%s>",
1128
+ g_type_tag_to_string(metadata->type.tag));
1129
+ return -1;
1130
+ case GI_TYPE_TAG_INT8:
1131
+ if (is_pointer) {
1132
+ return *((gint8 *)arg->v_pointer);
1133
+ } else {
1134
+ return arg->v_int8;
1135
+ }
1136
+ case GI_TYPE_TAG_UINT8:
1137
+ if (is_pointer) {
1138
+ return *((guint8 *)arg->v_pointer);
1139
+ } else {
1140
+ return arg->v_uint8;
1141
+ }
1142
+ case GI_TYPE_TAG_INT16:
1143
+ if (is_pointer) {
1144
+ return *((gint16 *)arg->v_pointer);
1145
+ } else {
1146
+ return arg->v_int16;
1147
+ }
1148
+ case GI_TYPE_TAG_UINT16:
1149
+ if (is_pointer) {
1150
+ return *((guint16 *)arg->v_pointer);
1151
+ } else {
1152
+ return arg->v_uint16;
1153
+ }
1154
+ case GI_TYPE_TAG_INT32:
1155
+ if (is_pointer) {
1156
+ return *((gint32 *)arg->v_pointer);
1157
+ } else {
1158
+ return arg->v_int32;
1159
+ }
1160
+ case GI_TYPE_TAG_UINT32:
1161
+ if (is_pointer) {
1162
+ return *((guint32 *)arg->v_pointer);
1163
+ } else {
1164
+ return arg->v_uint32;
1165
+ }
1166
+ case GI_TYPE_TAG_INT64:
1167
+ if (is_pointer) {
1168
+ return *((gint64 *)arg->v_pointer);
1169
+ } else {
1170
+ return arg->v_int64;
1171
+ }
1172
+ case GI_TYPE_TAG_UINT64:
1173
+ if (is_pointer) {
1174
+ return *((guint64 *)arg->v_pointer);
1175
+ } else {
1176
+ return arg->v_uint64;
1177
+ }
1178
+ case GI_TYPE_TAG_FLOAT:
1179
+ case GI_TYPE_TAG_DOUBLE:
1180
+ case GI_TYPE_TAG_GTYPE:
1181
+ case GI_TYPE_TAG_UTF8:
1182
+ case GI_TYPE_TAG_FILENAME:
1183
+ case GI_TYPE_TAG_ARRAY:
1184
+ case GI_TYPE_TAG_INTERFACE:
1185
+ case GI_TYPE_TAG_GLIST:
1186
+ case GI_TYPE_TAG_GSLIST:
1187
+ case GI_TYPE_TAG_GHASH:
1188
+ case GI_TYPE_TAG_ERROR:
1189
+ case GI_TYPE_TAG_UNICHAR:
1190
+ rb_raise(rb_eNotImpError,
1191
+ "TODO: invalid out array length argument?: <%s>",
1192
+ g_type_tag_to_string(metadata->type.tag));
1193
+ return -1;
1194
+ default:
1195
+ g_assert_not_reached();
1196
+ return -1;
1197
+ }
1198
+ }
1199
+
1200
+ static VALUE
1201
+ rb_gi_arguments_convert_arg_array_body(VALUE user_data)
1202
+ {
1203
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1204
+ GITypeInfo *type_info = data->arg_metadata->type_info;
1205
+
1206
+ gint length_index = g_type_info_get_array_length(type_info);
1207
+ gint64 length = -1;
1208
+ if (length_index != -1) {
1209
+ GIArgument *length_arg = NULL;
1210
+ RBGIArgMetadata *length_metadata =
1211
+ g_ptr_array_index(data->args->metadata, length_index);
1212
+ if (length_metadata->direction == GI_DIRECTION_OUT) {
1213
+ length_arg = &g_array_index(data->args->out_args,
1214
+ GIArgument,
1215
+ length_metadata->out_arg_index);
1216
+ } else if (length_metadata->direction == GI_DIRECTION_INOUT) {
1217
+ length_arg = &g_array_index(data->args->in_args,
1218
+ GIArgument,
1219
+ length_metadata->in_arg_index);
1220
+ }
1221
+
1222
+ if (length_arg) {
1223
+ gboolean is_pointer =
1224
+ !(length_metadata->array_metadata &&
1225
+ length_metadata->array_metadata->output_buffer_p);
1226
+ length =
1227
+ rb_gi_arguments_convert_arg_array_body_extract_length(
1228
+ length_arg,
1229
+ length_metadata,
1230
+ is_pointer);
1231
+ } else {
1232
+ length_arg = &g_array_index(data->args->in_args,
1233
+ GIArgument,
1234
+ length_metadata->in_arg_index);
1235
+ length =
1236
+ rb_gi_arguments_convert_arg_array_body_extract_length(
1237
+ length_arg,
1238
+ length_metadata,
1239
+ FALSE);
1240
+ }
1241
+ }
1242
+
1243
+ GIArrayType array_type = g_type_info_get_array_type(type_info);
1244
+ switch (array_type) {
1245
+ case GI_ARRAY_TYPE_C:
1246
+ return rb_gi_arguments_convert_arg_array_body_c(data, length);
1247
+ case GI_ARRAY_TYPE_ARRAY:
1248
+ return rb_gi_arguments_convert_arg_array_body_array(data);
1249
+ case GI_ARRAY_TYPE_PTR_ARRAY:
1250
+ rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[ptr-array] -> Ruby");
1251
+ return Qnil;
1252
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
1253
+ rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[byte-array] -> Ruby");
1254
+ return Qnil;
1255
+ default:
1256
+ g_assert_not_reached();
1257
+ return Qnil;
1258
+ }
1259
+ }
1260
+
1261
+ static VALUE
1262
+ rb_gi_arguments_convert_arg_array(RBGIArguments *args,
1263
+ GIArgument *arg,
1264
+ RBGIArgMetadata *arg_metadata)
1265
+ {
1266
+ ArrayLikeToRubyData data;
1267
+ data.args = args;
1268
+ data.arg = arg;
1269
+ data.arg_metadata = arg_metadata;
1270
+ data.element_type_info =
1271
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1272
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1273
+ data.interface_type_info = NULL;
1274
+ return rb_ensure(rb_gi_arguments_convert_arg_array_body,
1275
+ (VALUE)&data,
1276
+ rb_gi_arguments_convert_arg_array_like_ensure,
1277
+ (VALUE)&data);
1278
+ }
1279
+
1280
+ static VALUE
1281
+ rb_gi_arguments_convert_arg_glist_body_interface(ArrayLikeToRubyData *data)
1282
+ {
1283
+ data->interface_type_info =
1284
+ g_type_info_get_interface(data->element_type_info);
1285
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
1286
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
1287
+ switch (type) {
1288
+ case GI_INFO_TYPE_INVALID:
1289
+ case GI_INFO_TYPE_FUNCTION:
1290
+ case GI_INFO_TYPE_CALLBACK:
1291
+ rb_raise(rb_eNotImpError,
1292
+ "TODO: GIArgument(GList)[interface(%s)](%s) -> Ruby",
1293
+ g_info_type_to_string(type),
1294
+ g_type_name(gtype));
1295
+ return Qnil;
1296
+ case GI_INFO_TYPE_STRUCT:
1297
+ if (gtype == G_TYPE_NONE) {
1298
+ VALUE rb_arg = rb_ary_new();
1299
+ GList *node;
1300
+ for (node = data->arg->v_pointer; node; node = g_list_next(node)) {
1301
+ rb_ary_push(rb_arg,
1302
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
1303
+ node->data,
1304
+ TRUE));
1305
+ }
1306
+ return rb_arg;
1307
+ } else if (gtype == G_TYPE_VARIANT) {
1308
+ VALUE rb_arg = rb_ary_new();
1309
+ GList *node;
1310
+ for (node = data->arg->v_pointer; node; node = g_list_next(node)) {
1311
+ rb_ary_push(rb_arg, rbg_variant_to_ruby(node->data));
1312
+ }
1313
+ return rb_arg;
1314
+ } else {
1315
+ return BOXEDGLIST2RVAL(data->arg->v_pointer, gtype);
1316
+ }
1317
+ case GI_INFO_TYPE_BOXED:
1318
+ return BOXEDGLIST2RVAL(data->arg->v_pointer, gtype);
1319
+ case GI_INFO_TYPE_ENUM:
1320
+ case GI_INFO_TYPE_FLAGS:
1321
+ case GI_INFO_TYPE_OBJECT:
1322
+ case GI_INFO_TYPE_INTERFACE:
1323
+ return GOBJGLIST2RVAL(data->arg->v_pointer);
1324
+ case GI_INFO_TYPE_CONSTANT:
1325
+ case GI_INFO_TYPE_INVALID_0:
1326
+ case GI_INFO_TYPE_UNION:
1327
+ case GI_INFO_TYPE_VALUE:
1328
+ case GI_INFO_TYPE_SIGNAL:
1329
+ case GI_INFO_TYPE_VFUNC:
1330
+ case GI_INFO_TYPE_PROPERTY:
1331
+ case GI_INFO_TYPE_FIELD:
1332
+ case GI_INFO_TYPE_ARG:
1333
+ case GI_INFO_TYPE_TYPE:
1334
+ case GI_INFO_TYPE_UNRESOLVED:
1335
+ rb_raise(rb_eNotImpError,
1336
+ "TODO: GIArgument(GList)[interface(%s)](%s) -> Ruby",
1337
+ g_info_type_to_string(type),
1338
+ g_type_name(gtype));
1339
+ return Qnil;
1340
+ default:
1341
+ g_assert_not_reached();
1342
+ return Qnil;
1343
+ }
1344
+ }
1345
+
1346
+ static VALUE
1347
+ rb_gi_arguments_convert_arg_glist_body(VALUE user_data)
1348
+ {
1349
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1350
+
1351
+ switch (data->element_type_tag) {
1352
+ case GI_TYPE_TAG_VOID:
1353
+ case GI_TYPE_TAG_BOOLEAN:
1354
+ case GI_TYPE_TAG_INT8:
1355
+ case GI_TYPE_TAG_UINT8:
1356
+ case GI_TYPE_TAG_INT16:
1357
+ case GI_TYPE_TAG_UINT16:
1358
+ case GI_TYPE_TAG_INT32:
1359
+ case GI_TYPE_TAG_UINT32:
1360
+ case GI_TYPE_TAG_INT64:
1361
+ case GI_TYPE_TAG_UINT64:
1362
+ case GI_TYPE_TAG_FLOAT:
1363
+ case GI_TYPE_TAG_DOUBLE:
1364
+ case GI_TYPE_TAG_GTYPE:
1365
+ rb_raise(rb_eNotImpError,
1366
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1367
+ g_type_tag_to_string(data->element_type_tag));
1368
+ return Qnil;
1369
+ case GI_TYPE_TAG_UTF8:
1370
+ return CSTRGLIST2RVAL(data->arg->v_pointer);
1371
+ case GI_TYPE_TAG_FILENAME:
1372
+ return FILENAMEGLIST2RVAL(data->arg->v_pointer);
1373
+ case GI_TYPE_TAG_ARRAY:
1374
+ rb_raise(rb_eNotImpError,
1375
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1376
+ g_type_tag_to_string(data->element_type_tag));
1377
+ return Qnil;
1378
+ case GI_TYPE_TAG_INTERFACE:
1379
+ return rb_gi_arguments_convert_arg_glist_body_interface(data);
1380
+ case GI_TYPE_TAG_GLIST:
1381
+ case GI_TYPE_TAG_GSLIST:
1382
+ case GI_TYPE_TAG_GHASH:
1383
+ case GI_TYPE_TAG_ERROR:
1384
+ case GI_TYPE_TAG_UNICHAR:
1385
+ rb_raise(rb_eNotImpError,
1386
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1387
+ g_type_tag_to_string(data->element_type_tag));
1388
+ return Qnil;
1389
+ default:
1390
+ g_assert_not_reached();
1391
+ return Qnil;
1392
+ }
1393
+ }
1394
+
1395
+ static VALUE
1396
+ rb_gi_arguments_convert_arg_glist(RBGIArguments *args,
1397
+ GIArgument *arg,
1398
+ RBGIArgMetadata *arg_metadata)
1399
+ {
1400
+ ArrayLikeToRubyData data;
1401
+ data.args = args;
1402
+ data.arg = arg;
1403
+ data.arg_metadata = arg_metadata;
1404
+ data.element_type_info =
1405
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1406
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1407
+ data.interface_type_info = NULL;
1408
+ return rb_ensure(rb_gi_arguments_convert_arg_glist_body,
1409
+ (VALUE)&data,
1410
+ rb_gi_arguments_convert_arg_array_like_ensure,
1411
+ (VALUE)&data);
1412
+ }
1413
+
1414
+ static VALUE
1415
+ rb_gi_arguments_convert_arg_gslist_body_interface(ArrayLikeToRubyData *data)
1416
+ {
1417
+ data->interface_type_info =
1418
+ g_type_info_get_interface(data->element_type_info);
1419
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
1420
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
1421
+ switch (type) {
1422
+ case GI_INFO_TYPE_INVALID:
1423
+ case GI_INFO_TYPE_FUNCTION:
1424
+ case GI_INFO_TYPE_CALLBACK:
1425
+ rb_raise(rb_eNotImpError,
1426
+ "TODO: GIArgument(GSList)[interface(%s)](%s) -> Ruby",
1427
+ g_info_type_to_string(type),
1428
+ g_type_name(gtype));
1429
+ return Qnil;
1430
+ case GI_INFO_TYPE_STRUCT:
1431
+ if (gtype == G_TYPE_NONE) {
1432
+ VALUE rb_arg = rb_ary_new();
1433
+ GSList *node;
1434
+ for (node = data->arg->v_pointer; node; node = g_slist_next(node)) {
1435
+ rb_ary_push(rb_arg,
1436
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
1437
+ node->data,
1438
+ TRUE));
1439
+ }
1440
+ return rb_arg;
1441
+ } else if (gtype == G_TYPE_VARIANT) {
1442
+ VALUE rb_arg = rb_ary_new();
1443
+ GSList *node;
1444
+ for (node = data->arg->v_pointer; node; node = g_slist_next(node)) {
1445
+ rb_ary_push(rb_arg, rbg_variant_to_ruby(node->data));
1446
+ }
1447
+ return rb_arg;
1448
+ } else {
1449
+ return BOXEDGSLIST2RVAL(data->arg->v_pointer, gtype);
1450
+ }
1451
+ case GI_INFO_TYPE_BOXED:
1452
+ return BOXEDGSLIST2RVAL(data->arg->v_pointer, gtype);
1453
+ case GI_INFO_TYPE_ENUM:
1454
+ case GI_INFO_TYPE_FLAGS:
1455
+ case GI_INFO_TYPE_OBJECT:
1456
+ case GI_INFO_TYPE_INTERFACE:
1457
+ return GOBJGSLIST2RVAL(data->arg->v_pointer);
1458
+ case GI_INFO_TYPE_CONSTANT:
1459
+ case GI_INFO_TYPE_INVALID_0:
1460
+ case GI_INFO_TYPE_UNION:
1461
+ case GI_INFO_TYPE_VALUE:
1462
+ case GI_INFO_TYPE_SIGNAL:
1463
+ case GI_INFO_TYPE_VFUNC:
1464
+ case GI_INFO_TYPE_PROPERTY:
1465
+ case GI_INFO_TYPE_FIELD:
1466
+ case GI_INFO_TYPE_ARG:
1467
+ case GI_INFO_TYPE_TYPE:
1468
+ case GI_INFO_TYPE_UNRESOLVED:
1469
+ rb_raise(rb_eNotImpError,
1470
+ "TODO: GIArgument(GSList)[interface(%s)](%s) -> Ruby",
1471
+ g_info_type_to_string(type),
1472
+ g_type_name(gtype));
1473
+ return Qnil;
1474
+ default:
1475
+ g_assert_not_reached();
1476
+ return Qnil;
1477
+ }
1478
+ }
1479
+
1480
+ static VALUE
1481
+ rb_gi_arguments_convert_arg_gslist_body(VALUE user_data)
1482
+ {
1483
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1484
+
1485
+ switch (data->element_type_tag) {
1486
+ case GI_TYPE_TAG_VOID:
1487
+ case GI_TYPE_TAG_BOOLEAN:
1488
+ case GI_TYPE_TAG_INT8:
1489
+ case GI_TYPE_TAG_UINT8:
1490
+ case GI_TYPE_TAG_INT16:
1491
+ case GI_TYPE_TAG_UINT16:
1492
+ case GI_TYPE_TAG_INT32:
1493
+ case GI_TYPE_TAG_UINT32:
1494
+ case GI_TYPE_TAG_INT64:
1495
+ case GI_TYPE_TAG_UINT64:
1496
+ case GI_TYPE_TAG_FLOAT:
1497
+ case GI_TYPE_TAG_DOUBLE:
1498
+ case GI_TYPE_TAG_GTYPE:
1499
+ rb_raise(rb_eNotImpError,
1500
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1501
+ g_type_tag_to_string(data->element_type_tag));
1502
+ return Qnil;
1503
+ case GI_TYPE_TAG_UTF8:
1504
+ return CSTRGSLIST2RVAL(data->arg->v_pointer);
1505
+ case GI_TYPE_TAG_FILENAME:
1506
+ return FILENAMEGSLIST2RVAL(data->arg->v_pointer);
1507
+ case GI_TYPE_TAG_ARRAY:
1508
+ rb_raise(rb_eNotImpError,
1509
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1510
+ g_type_tag_to_string(data->element_type_tag));
1511
+ return Qnil;
1512
+ case GI_TYPE_TAG_INTERFACE:
1513
+ return rb_gi_arguments_convert_arg_gslist_body_interface(data);
1514
+ case GI_TYPE_TAG_GLIST:
1515
+ case GI_TYPE_TAG_GSLIST:
1516
+ case GI_TYPE_TAG_GHASH:
1517
+ case GI_TYPE_TAG_ERROR:
1518
+ case GI_TYPE_TAG_UNICHAR:
1519
+ rb_raise(rb_eNotImpError,
1520
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1521
+ g_type_tag_to_string(data->element_type_tag));
1522
+ return Qnil;
1523
+ default:
1524
+ g_assert_not_reached();
1525
+ return Qnil;
1526
+ }
1527
+ }
1528
+
1529
+ static VALUE
1530
+ rb_gi_arguments_convert_arg_gslist(RBGIArguments *args,
1531
+ GIArgument *arg,
1532
+ RBGIArgMetadata *arg_metadata)
1533
+ {
1534
+ ArrayLikeToRubyData data;
1535
+ data.args = args;
1536
+ data.arg = arg;
1537
+ data.arg_metadata = arg_metadata;
1538
+ data.element_type_info =
1539
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1540
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1541
+ data.interface_type_info = NULL;
1542
+ return rb_ensure(rb_gi_arguments_convert_arg_gslist_body,
1543
+ (VALUE)&data,
1544
+ rb_gi_arguments_convert_arg_array_like_ensure,
1545
+ (VALUE)&data);
1546
+ }
1547
+
1548
+ typedef struct {
1549
+ RBGIArguments *args;
1550
+ GIArgument *arg;
1551
+ RBGIArgMetadata *arg_metadata;
1552
+ VALUE rb_table;
1553
+ RBGIArgMetadata *key_metadata;
1554
+ RBGIArgMetadata *value_metadata;
1555
+ } GHashToRubyData;
1556
+
1557
+ static void
1558
+ rb_gi_arguments_convert_arg_ghash_foreach_body(gpointer key,
1559
+ gpointer value,
1560
+ gpointer user_data)
1561
+ {
1562
+ GHashToRubyData *data = user_data;
1563
+ VALUE rb_key;
1564
+ VALUE rb_value;
1565
+
1566
+ switch (data->key_metadata->type.tag) {
1567
+ case GI_TYPE_TAG_VOID:
1568
+ case GI_TYPE_TAG_BOOLEAN:
1569
+ case GI_TYPE_TAG_INT8:
1570
+ case GI_TYPE_TAG_UINT8:
1571
+ case GI_TYPE_TAG_INT16:
1572
+ case GI_TYPE_TAG_UINT16:
1573
+ case GI_TYPE_TAG_INT32:
1574
+ case GI_TYPE_TAG_UINT32:
1575
+ case GI_TYPE_TAG_INT64:
1576
+ case GI_TYPE_TAG_UINT64:
1577
+ case GI_TYPE_TAG_FLOAT:
1578
+ case GI_TYPE_TAG_DOUBLE:
1579
+ case GI_TYPE_TAG_GTYPE:
1580
+ rb_raise(rb_eNotImpError,
1581
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1582
+ g_type_tag_to_string(data->key_metadata->type.tag),
1583
+ g_type_tag_to_string(data->value_metadata->type.tag));
1584
+ break;
1585
+ case GI_TYPE_TAG_UTF8:
1586
+ rb_key = CSTR2RVAL(key);
1587
+ break;
1588
+ case GI_TYPE_TAG_FILENAME:
1589
+ case GI_TYPE_TAG_ARRAY:
1590
+ rb_raise(rb_eNotImpError,
1591
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1592
+ g_type_tag_to_string(data->key_metadata->type.tag),
1593
+ g_type_tag_to_string(data->value_metadata->type.tag));
1594
+ break;
1595
+ case GI_TYPE_TAG_INTERFACE:
1596
+ {
1597
+ GIArgument key_arg;
1598
+ key_arg.v_pointer = key;
1599
+ rb_key = rb_gi_arguments_convert_arg_interface(data->args,
1600
+ &key_arg,
1601
+ data->key_metadata,
1602
+ FALSE);
1603
+ }
1604
+ break;
1605
+ case GI_TYPE_TAG_GLIST:
1606
+ case GI_TYPE_TAG_GSLIST:
1607
+ case GI_TYPE_TAG_GHASH:
1608
+ case GI_TYPE_TAG_ERROR:
1609
+ case GI_TYPE_TAG_UNICHAR:
1610
+ rb_raise(rb_eNotImpError,
1611
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1612
+ g_type_tag_to_string(data->key_metadata->type.tag),
1613
+ g_type_tag_to_string(data->value_metadata->type.tag));
1614
+ break;
1615
+ default:
1616
+ g_assert_not_reached();
1617
+ break;
1618
+ }
1619
+
1620
+ switch (data->value_metadata->type.tag) {
1621
+ case GI_TYPE_TAG_VOID:
1622
+ case GI_TYPE_TAG_BOOLEAN:
1623
+ case GI_TYPE_TAG_INT8:
1624
+ case GI_TYPE_TAG_UINT8:
1625
+ case GI_TYPE_TAG_INT16:
1626
+ case GI_TYPE_TAG_UINT16:
1627
+ case GI_TYPE_TAG_INT32:
1628
+ case GI_TYPE_TAG_UINT32:
1629
+ case GI_TYPE_TAG_INT64:
1630
+ case GI_TYPE_TAG_UINT64:
1631
+ case GI_TYPE_TAG_FLOAT:
1632
+ case GI_TYPE_TAG_DOUBLE:
1633
+ case GI_TYPE_TAG_GTYPE:
1634
+ rb_raise(rb_eNotImpError,
1635
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1636
+ g_type_tag_to_string(data->key_metadata->type.tag),
1637
+ g_type_tag_to_string(data->value_metadata->type.tag));
1638
+ break;
1639
+ case GI_TYPE_TAG_UTF8:
1640
+ rb_value = CSTR2RVAL(value);
1641
+ break;
1642
+ case GI_TYPE_TAG_FILENAME:
1643
+ case GI_TYPE_TAG_ARRAY:
1644
+ rb_raise(rb_eNotImpError,
1645
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1646
+ g_type_tag_to_string(data->key_metadata->type.tag),
1647
+ g_type_tag_to_string(data->value_metadata->type.tag));
1648
+ break;
1649
+ case GI_TYPE_TAG_INTERFACE:
1650
+ {
1651
+ GIArgument value_arg;
1652
+ value_arg.v_pointer = value;
1653
+ rb_value = rb_gi_arguments_convert_arg_interface(
1654
+ data->args,
1655
+ &value_arg,
1656
+ data->value_metadata,
1657
+ FALSE);
1658
+ }
1659
+ break;
1660
+ case GI_TYPE_TAG_GLIST:
1661
+ case GI_TYPE_TAG_GSLIST:
1662
+ case GI_TYPE_TAG_GHASH:
1663
+ case GI_TYPE_TAG_ERROR:
1664
+ case GI_TYPE_TAG_UNICHAR:
1665
+ rb_raise(rb_eNotImpError,
1666
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1667
+ g_type_tag_to_string(data->key_metadata->type.tag),
1668
+ g_type_tag_to_string(data->value_metadata->type.tag));
1669
+ break;
1670
+ default:
1671
+ g_assert_not_reached();
1672
+ break;
1673
+ }
1674
+
1675
+ rb_hash_aset(data->rb_table, rb_key, rb_value);
1676
+ }
1677
+
1678
+ static VALUE
1679
+ rb_gi_arguments_convert_arg_ghash_body(VALUE user_data)
1680
+ {
1681
+ GHashToRubyData *data = (GHashToRubyData *)user_data;
1682
+ g_hash_table_foreach(data->arg->v_pointer,
1683
+ rb_gi_arguments_convert_arg_ghash_foreach_body,
1684
+ data);
1685
+ return data->rb_table;
1686
+ }
1687
+
1688
+ static VALUE
1689
+ rb_gi_arguments_convert_arg_ghash_ensure(VALUE user_data)
1690
+ {
1691
+ GHashToRubyData *data = (GHashToRubyData *)user_data;
1692
+ rb_gi_arg_metadata_clear(data->key_metadata);
1693
+ rb_gi_arg_metadata_clear(data->value_metadata);
1694
+ return Qnil;
1695
+ }
1696
+
1697
+ static VALUE
1698
+ rb_gi_arguments_convert_arg_ghash(RBGIArguments *args,
1699
+ GIArgument *arg,
1700
+ RBGIArgMetadata *arg_metadata)
1701
+ {
1702
+ GHashToRubyData data;
1703
+
1704
+ data.args = args;
1705
+ data.arg = arg;
1706
+ data.arg_metadata = arg_metadata;
1707
+ data.rb_table = rb_hash_new();
1708
+
1709
+ GITypeInfo *type_info = arg_metadata->type_info;
1710
+
1711
+ RBGIArgMetadata key_metadata;
1712
+ rb_gi_arg_metadata_init_type_info(&key_metadata,
1713
+ g_type_info_get_param_type(type_info, 0));
1714
+ data.key_metadata = &key_metadata;
1715
+
1716
+ RBGIArgMetadata value_metadata;
1717
+ rb_gi_arg_metadata_init_type_info(&value_metadata,
1718
+ g_type_info_get_param_type(type_info, 1));
1719
+ data.value_metadata = &value_metadata;
1720
+
1721
+ return rb_ensure(rb_gi_arguments_convert_arg_ghash_body, (VALUE)&data,
1722
+ rb_gi_arguments_convert_arg_ghash_ensure, (VALUE)&data);
1723
+ }
1724
+
1725
+ static VALUE
1726
+ rb_gi_arguments_convert_arg_unichar(RBGIArguments *args,
1727
+ GIArgument *arg,
1728
+ RBGIArgMetadata *arg_metadata)
1729
+ {
1730
+ GError *error = NULL;
1731
+ gunichar ucs4_character = arg->v_uint32;
1732
+ gchar *utf8_string = g_ucs4_to_utf8(&ucs4_character, 1, NULL, NULL, &error);
1733
+ if (error) {
1734
+ RG_RAISE_ERROR(error);
1735
+ }
1736
+ return CSTR2RVAL_FREE(utf8_string);
1737
+ }
1738
+
1739
+ VALUE
1740
+ rb_gi_arguments_convert_arg(RBGIArguments *args,
1741
+ GIArgument *arg,
1742
+ RBGIArgMetadata *arg_metadata,
1743
+ gboolean duplicate)
1744
+ {
1745
+ GITypeTag type_tag = g_type_info_get_tag(arg_metadata->type_info);
1746
+ switch (type_tag) {
1747
+ case GI_TYPE_TAG_VOID:
1748
+ if (g_type_info_is_pointer(arg_metadata->type_info)) {
1749
+ return POINTER2NUM(arg->v_pointer);
1750
+ } else {
1751
+ return Qnil;
1752
+ }
1753
+ case GI_TYPE_TAG_BOOLEAN:
1754
+ return CBOOL2RVAL(arg->v_boolean);
1755
+ case GI_TYPE_TAG_INT8:
1756
+ return INT2NUM(arg->v_int8);
1757
+ case GI_TYPE_TAG_UINT8:
1758
+ return UINT2NUM(arg->v_uint8);
1759
+ case GI_TYPE_TAG_INT16:
1760
+ return INT2NUM(arg->v_int16);
1761
+ case GI_TYPE_TAG_UINT16:
1762
+ return UINT2NUM(arg->v_uint16);
1763
+ case GI_TYPE_TAG_INT32:
1764
+ return INT2NUM(arg->v_int32);
1765
+ case GI_TYPE_TAG_UINT32:
1766
+ return UINT2NUM(arg->v_uint32);
1767
+ case GI_TYPE_TAG_INT64:
1768
+ return LL2NUM(arg->v_int64);
1769
+ case GI_TYPE_TAG_UINT64:
1770
+ return ULL2NUM(arg->v_uint64);
1771
+ case GI_TYPE_TAG_FLOAT:
1772
+ return DBL2NUM(arg->v_float);
1773
+ case GI_TYPE_TAG_DOUBLE:
1774
+ return DBL2NUM(arg->v_double);
1775
+ case GI_TYPE_TAG_GTYPE:
1776
+ if (arg->v_size == G_TYPE_INVALID) {
1777
+ return Qnil;
1778
+ } else {
1779
+ return rbgobj_gtype_new(arg->v_size);
1780
+ }
1781
+ case GI_TYPE_TAG_UTF8:
1782
+ return CSTR2RVAL(arg->v_string);
1783
+ case GI_TYPE_TAG_FILENAME:
1784
+ return CSTRFILENAME2RVAL(arg->v_string);
1785
+ case GI_TYPE_TAG_ARRAY:
1786
+ return rb_gi_arguments_convert_arg_array(args, arg, arg_metadata);
1787
+ case GI_TYPE_TAG_INTERFACE:
1788
+ return rb_gi_arguments_convert_arg_interface(args,
1789
+ arg,
1790
+ arg_metadata,
1791
+ duplicate);
1792
+ case GI_TYPE_TAG_GLIST:
1793
+ return rb_gi_arguments_convert_arg_glist(args, arg, arg_metadata);
1794
+ case GI_TYPE_TAG_GSLIST:
1795
+ return rb_gi_arguments_convert_arg_gslist(args, arg, arg_metadata);
1796
+ case GI_TYPE_TAG_GHASH:
1797
+ return rb_gi_arguments_convert_arg_ghash(args, arg, arg_metadata);
1798
+ case GI_TYPE_TAG_ERROR:
1799
+ return GERROR2RVAL(arg->v_pointer);
1800
+ case GI_TYPE_TAG_UNICHAR:
1801
+ return rb_gi_arguments_convert_arg_unichar(args, arg, arg_metadata);
1802
+ default:
1803
+ g_assert_not_reached();
1804
+ return Qnil;
1805
+ }
1806
+ }
1807
+
1808
+ typedef struct {
1809
+ RBGIArguments *args;
1810
+ GIArgument *value;
1811
+ RBGIArgMetadata *metadata;
1812
+ } ReturnValueToRubyData;
1813
+
1814
+ static VALUE
1815
+ rb_gi_arguments_convert_return_value_body(VALUE user_data)
1816
+ {
1817
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
1818
+ return rb_gi_arguments_convert_arg(data->args,
1819
+ data->value,
1820
+ data->metadata,
1821
+ FALSE);
1822
+ }
1823
+
1824
+ static void
1825
+ rb_gi_arguments_convert_return_value_free_container(ReturnValueToRubyData *data)
1826
+ {
1827
+ GITypeTag type_tag = data->metadata->type.tag;
1828
+ switch (type_tag) {
1829
+ case GI_TYPE_TAG_VOID:
1830
+ case GI_TYPE_TAG_BOOLEAN:
1831
+ case GI_TYPE_TAG_INT8:
1832
+ case GI_TYPE_TAG_UINT8:
1833
+ case GI_TYPE_TAG_INT16:
1834
+ case GI_TYPE_TAG_UINT16:
1835
+ case GI_TYPE_TAG_INT32:
1836
+ case GI_TYPE_TAG_UINT32:
1837
+ case GI_TYPE_TAG_INT64:
1838
+ case GI_TYPE_TAG_UINT64:
1839
+ case GI_TYPE_TAG_FLOAT:
1840
+ case GI_TYPE_TAG_DOUBLE:
1841
+ case GI_TYPE_TAG_GTYPE:
1842
+ case GI_TYPE_TAG_UTF8:
1843
+ case GI_TYPE_TAG_FILENAME:
1844
+ rb_raise(rb_eNotImpError,
1845
+ "TODO: free GIArgument(%s) as container",
1846
+ g_type_tag_to_string(type_tag));
1847
+ break;
1848
+ case GI_TYPE_TAG_ARRAY:
1849
+ g_free(data->value->v_pointer);
1850
+ break;
1851
+ case GI_TYPE_TAG_INTERFACE:
1852
+ rb_raise(rb_eNotImpError,
1853
+ "TODO: free GIArgument(%s) as container",
1854
+ g_type_tag_to_string(type_tag));
1855
+ break;
1856
+ case GI_TYPE_TAG_GLIST:
1857
+ g_list_free(data->value->v_pointer);
1858
+ break;
1859
+ case GI_TYPE_TAG_GSLIST:
1860
+ g_slist_free(data->value->v_pointer);
1861
+ break;
1862
+ case GI_TYPE_TAG_GHASH:
1863
+ g_hash_table_unref(data->value->v_pointer);
1864
+ break;
1865
+ case GI_TYPE_TAG_ERROR:
1866
+ case GI_TYPE_TAG_UNICHAR:
1867
+ rb_raise(rb_eNotImpError,
1868
+ "TODO: free GIArgument(%s) as container",
1869
+ g_type_tag_to_string(type_tag));
1870
+ break;
1871
+ default:
1872
+ g_assert_not_reached();
1873
+ break;
1874
+ }
1875
+ }
1876
+
1877
+ static void
1878
+ rb_gi_arguments_convert_return_value_free_everything_array_c(
1879
+ ReturnValueToRubyData *data)
1880
+ {
1881
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
1882
+ switch (element_type_tag) {
1883
+ case GI_TYPE_TAG_VOID:
1884
+ rb_raise(rb_eNotImpError,
1885
+ "TODO: free GIArgument(array)[c][%s] everything",
1886
+ g_type_tag_to_string(element_type_tag));
1887
+ break;
1888
+ case GI_TYPE_TAG_BOOLEAN:
1889
+ case GI_TYPE_TAG_INT8:
1890
+ case GI_TYPE_TAG_UINT8:
1891
+ case GI_TYPE_TAG_INT16:
1892
+ case GI_TYPE_TAG_UINT16:
1893
+ case GI_TYPE_TAG_INT32:
1894
+ case GI_TYPE_TAG_UINT32:
1895
+ case GI_TYPE_TAG_INT64:
1896
+ case GI_TYPE_TAG_UINT64:
1897
+ case GI_TYPE_TAG_FLOAT:
1898
+ case GI_TYPE_TAG_DOUBLE:
1899
+ g_free(data->value->v_pointer);
1900
+ break;
1901
+ case GI_TYPE_TAG_GTYPE:
1902
+ rb_raise(rb_eNotImpError,
1903
+ "TODO: free GIArgument(array)[c][%s] everything",
1904
+ g_type_tag_to_string(element_type_tag));
1905
+ break;
1906
+ case GI_TYPE_TAG_UTF8:
1907
+ g_strfreev(data->value->v_pointer);
1908
+ break;
1909
+ case GI_TYPE_TAG_FILENAME:
1910
+ g_strfreev(data->value->v_pointer);
1911
+ break;
1912
+ case GI_TYPE_TAG_ARRAY:
1913
+ case GI_TYPE_TAG_INTERFACE:
1914
+ case GI_TYPE_TAG_GLIST:
1915
+ case GI_TYPE_TAG_GSLIST:
1916
+ case GI_TYPE_TAG_GHASH:
1917
+ case GI_TYPE_TAG_ERROR:
1918
+ case GI_TYPE_TAG_UNICHAR:
1919
+ rb_raise(rb_eNotImpError,
1920
+ "TODO: free GIArgument(array)[c][%s] everything",
1921
+ g_type_tag_to_string(element_type_tag));
1922
+ break;
1923
+ default:
1924
+ g_assert_not_reached();
1925
+ break;
1926
+ }
1927
+ }
1928
+
1929
+ static void
1930
+ rb_gi_arguments_convert_return_value_free_everything_array(
1931
+ ReturnValueToRubyData *data)
1932
+ {
1933
+ switch (data->metadata->array_type) {
1934
+ case GI_ARRAY_TYPE_C:
1935
+ rb_gi_arguments_convert_return_value_free_everything_array_c(data);
1936
+ break;
1937
+ case GI_ARRAY_TYPE_ARRAY:
1938
+ g_array_free(data->value->v_pointer, TRUE);
1939
+ break;
1940
+ case GI_ARRAY_TYPE_PTR_ARRAY:
1941
+ g_ptr_array_free(data->value->v_pointer, TRUE);
1942
+ break;
1943
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
1944
+ g_byte_array_free(data->value->v_pointer, TRUE);
1945
+ break;
1946
+ default:
1947
+ g_assert_not_reached();
1948
+ break;
1949
+ }
1950
+ }
1951
+
1952
+ static void
1953
+ rb_gi_arguments_convert_return_value_free_everything_interface(
1954
+ ReturnValueToRubyData *data)
1955
+ {
1956
+ if (!data->value->v_pointer) {
1957
+ return;
1958
+ }
1959
+
1960
+ GIInfoType type = data->metadata->type.interface_type;
1961
+ GType gtype = data->metadata->type.interface_gtype;
1962
+ switch (type) {
1963
+ case GI_INFO_TYPE_INVALID:
1964
+ case GI_INFO_TYPE_FUNCTION:
1965
+ case GI_INFO_TYPE_CALLBACK:
1966
+ rb_raise(rb_eNotImpError,
1967
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1968
+ g_info_type_to_string(type),
1969
+ g_type_name(gtype));
1970
+ break;
1971
+ case GI_INFO_TYPE_STRUCT:
1972
+ if (gtype == G_TYPE_INVALID) {
1973
+ xfree(data->value->v_pointer);
1974
+ } else if (gtype == G_TYPE_VARIANT) {
1975
+ g_variant_unref(data->value->v_pointer);
1976
+ } else {
1977
+ if (G_TYPE_IS_BOXED(gtype)) {
1978
+ g_boxed_free(gtype, data->value->v_pointer);
1979
+ } else {
1980
+ rbgobj_instance_unref(data->value->v_pointer);
1981
+ }
1982
+ }
1983
+ break;
1984
+ case GI_INFO_TYPE_BOXED:
1985
+ case GI_INFO_TYPE_ENUM:
1986
+ case GI_INFO_TYPE_FLAGS:
1987
+ rb_raise(rb_eNotImpError,
1988
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1989
+ g_info_type_to_string(type),
1990
+ g_type_name(gtype));
1991
+ break;
1992
+ case GI_INFO_TYPE_OBJECT:
1993
+ {
1994
+ GObject *object = data->value->v_pointer;
1995
+ if (g_object_is_floating(object)) {
1996
+ g_object_ref_sink(object);
1997
+ }
1998
+ g_object_unref(object);
1999
+ }
2000
+ break;
2001
+ case GI_INFO_TYPE_INTERFACE:
2002
+ g_object_unref(data->value->v_pointer);
2003
+ break;
2004
+ case GI_INFO_TYPE_CONSTANT:
2005
+ rb_raise(rb_eNotImpError,
2006
+ "TODO: free GIArgument(interface(%s))(%s) everything",
2007
+ g_info_type_to_string(type),
2008
+ g_type_name(gtype));
2009
+ break;
2010
+ case GI_INFO_TYPE_INVALID_0:
2011
+ g_assert_not_reached();
2012
+ break;
2013
+ case GI_INFO_TYPE_UNION:
2014
+ if (gtype == G_TYPE_NONE) {
2015
+ rb_raise(rb_eNotImpError,
2016
+ "TODO: free GIArgument(interface(%s))(%s) everything",
2017
+ g_info_type_to_string(type),
2018
+ g_type_name(gtype));
2019
+ } else {
2020
+ g_boxed_free(gtype, data->value->v_pointer);
2021
+ }
2022
+ break;
2023
+ case GI_INFO_TYPE_VALUE:
2024
+ case GI_INFO_TYPE_SIGNAL:
2025
+ case GI_INFO_TYPE_VFUNC:
2026
+ case GI_INFO_TYPE_PROPERTY:
2027
+ case GI_INFO_TYPE_FIELD:
2028
+ case GI_INFO_TYPE_ARG:
2029
+ case GI_INFO_TYPE_TYPE:
2030
+ case GI_INFO_TYPE_UNRESOLVED:
2031
+ rb_raise(rb_eNotImpError,
2032
+ "TODO: free GIArgument(interface(%s))(%s) everything",
2033
+ g_info_type_to_string(type),
2034
+ g_type_name(gtype));
2035
+ break;
2036
+ default:
2037
+ g_assert_not_reached();
2038
+ break;
2039
+ }
2040
+ }
2041
+
2042
+ static void
2043
+ rb_gi_boxed_free_callback(gpointer boxed, gpointer user_data)
2044
+ {
2045
+ GType *gtype = user_data;
2046
+ g_boxed_free(*gtype, boxed);
2047
+ }
2048
+
2049
+ static void
2050
+ rb_gi_arguments_convert_return_value_free_everything_glist_interface(
2051
+ ReturnValueToRubyData *data)
2052
+ {
2053
+ GIInfoType type = data->metadata->element_type.interface_type;
2054
+ GType gtype = data->metadata->element_type.interface_gtype;
2055
+ switch (type) {
2056
+ case GI_INFO_TYPE_INVALID:
2057
+ case GI_INFO_TYPE_FUNCTION:
2058
+ case GI_INFO_TYPE_CALLBACK:
2059
+ rb_raise(rb_eNotImpError,
2060
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2061
+ g_info_type_to_string(type),
2062
+ g_type_name(gtype));
2063
+ break;
2064
+ case GI_INFO_TYPE_STRUCT:
2065
+ if (gtype == G_TYPE_NONE) {
2066
+ rb_raise(rb_eNotImpError,
2067
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2068
+ g_info_type_to_string(type),
2069
+ g_type_name(gtype));
2070
+ } else if (gtype == G_TYPE_VARIANT) {
2071
+ g_list_free_full(data->value->v_pointer,
2072
+ (GDestroyNotify)g_variant_unref);
2073
+ } else {
2074
+ g_list_foreach(data->value->v_pointer,
2075
+ rb_gi_boxed_free_callback,
2076
+ &gtype);
2077
+ g_list_free(data->value->v_pointer);
2078
+ }
2079
+ break;
2080
+ case GI_INFO_TYPE_BOXED:
2081
+ g_list_foreach(data->value->v_pointer,
2082
+ rb_gi_boxed_free_callback,
2083
+ &gtype);
2084
+ g_list_free(data->value->v_pointer);
2085
+ break;
2086
+ case GI_INFO_TYPE_ENUM:
2087
+ case GI_INFO_TYPE_FLAGS:
2088
+ rb_raise(rb_eNotImpError,
2089
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2090
+ g_info_type_to_string(type),
2091
+ g_type_name(gtype));
2092
+ break;
2093
+ case GI_INFO_TYPE_OBJECT:
2094
+ case GI_INFO_TYPE_INTERFACE:
2095
+ g_list_free_full(data->value->v_pointer, g_object_unref);
2096
+ break;
2097
+ case GI_INFO_TYPE_CONSTANT:
2098
+ case GI_INFO_TYPE_INVALID_0:
2099
+ case GI_INFO_TYPE_UNION:
2100
+ case GI_INFO_TYPE_VALUE:
2101
+ case GI_INFO_TYPE_SIGNAL:
2102
+ case GI_INFO_TYPE_VFUNC:
2103
+ case GI_INFO_TYPE_PROPERTY:
2104
+ case GI_INFO_TYPE_FIELD:
2105
+ case GI_INFO_TYPE_ARG:
2106
+ case GI_INFO_TYPE_TYPE:
2107
+ case GI_INFO_TYPE_UNRESOLVED:
2108
+ rb_raise(rb_eNotImpError,
2109
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2110
+ g_info_type_to_string(type),
2111
+ g_type_name(gtype));
2112
+ break;
2113
+ default:
2114
+ g_assert_not_reached();
2115
+ break;
2116
+ }
2117
+ }
2118
+
2119
+ static void
2120
+ rb_gi_arguments_convert_return_value_free_everything_glist(
2121
+ ReturnValueToRubyData *data)
2122
+ {
2123
+ if (!data->value->v_pointer)
2124
+ return;
2125
+
2126
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
2127
+ switch (element_type_tag) {
2128
+ case GI_TYPE_TAG_VOID:
2129
+ case GI_TYPE_TAG_BOOLEAN:
2130
+ case GI_TYPE_TAG_INT8:
2131
+ case GI_TYPE_TAG_UINT8:
2132
+ case GI_TYPE_TAG_INT16:
2133
+ case GI_TYPE_TAG_UINT16:
2134
+ case GI_TYPE_TAG_INT32:
2135
+ case GI_TYPE_TAG_UINT32:
2136
+ case GI_TYPE_TAG_INT64:
2137
+ case GI_TYPE_TAG_UINT64:
2138
+ case GI_TYPE_TAG_FLOAT:
2139
+ case GI_TYPE_TAG_DOUBLE:
2140
+ case GI_TYPE_TAG_GTYPE:
2141
+ rb_raise(rb_eNotImpError,
2142
+ "TODO: free GIArgument(GList)[%s] everything",
2143
+ g_type_tag_to_string(element_type_tag));
2144
+ break;
2145
+ case GI_TYPE_TAG_UTF8:
2146
+ case GI_TYPE_TAG_FILENAME:
2147
+ g_list_free_full(data->value->v_pointer, g_free);
2148
+ break;
2149
+ case GI_TYPE_TAG_ARRAY:
2150
+ rb_raise(rb_eNotImpError,
2151
+ "TODO: free GIArgument(GList)[%s] everything",
2152
+ g_type_tag_to_string(element_type_tag));
2153
+ break;
2154
+ case GI_TYPE_TAG_INTERFACE:
2155
+ rb_gi_arguments_convert_return_value_free_everything_glist_interface(data);
2156
+ break;
2157
+ case GI_TYPE_TAG_GLIST:
2158
+ case GI_TYPE_TAG_GSLIST:
2159
+ case GI_TYPE_TAG_GHASH:
2160
+ case GI_TYPE_TAG_ERROR:
2161
+ case GI_TYPE_TAG_UNICHAR:
2162
+ rb_raise(rb_eNotImpError,
2163
+ "TODO: free GIArgument(GList)[%s] everything",
2164
+ g_type_tag_to_string(element_type_tag));
2165
+ break;
2166
+ default:
2167
+ g_assert_not_reached();
2168
+ break;
2169
+ }
2170
+ }
2171
+
2172
+ static void
2173
+ rb_gi_arguments_convert_return_value_free_everything_gslist_interface(
2174
+ ReturnValueToRubyData *data)
2175
+ {
2176
+ GIInfoType type = data->metadata->element_type.interface_type;
2177
+ GType gtype = data->metadata->element_type.interface_gtype;
2178
+ switch (type) {
2179
+ case GI_INFO_TYPE_INVALID:
2180
+ case GI_INFO_TYPE_FUNCTION:
2181
+ case GI_INFO_TYPE_CALLBACK:
2182
+ rb_raise(rb_eNotImpError,
2183
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2184
+ g_info_type_to_string(type),
2185
+ g_type_name(gtype));
2186
+ break;
2187
+ case GI_INFO_TYPE_STRUCT:
2188
+ if (gtype == G_TYPE_NONE) {
2189
+ rb_raise(rb_eNotImpError,
2190
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2191
+ g_info_type_to_string(type),
2192
+ g_type_name(gtype));
2193
+ } else {
2194
+ g_slist_foreach(data->value->v_pointer,
2195
+ rb_gi_boxed_free_callback,
2196
+ &gtype);
2197
+ g_slist_free(data->value->v_pointer);
2198
+ }
2199
+ break;
2200
+ case GI_INFO_TYPE_BOXED:
2201
+ g_slist_foreach(data->value->v_pointer,
2202
+ rb_gi_boxed_free_callback,
2203
+ &gtype);
2204
+ g_slist_free(data->value->v_pointer);
2205
+ break;
2206
+ case GI_INFO_TYPE_ENUM:
2207
+ case GI_INFO_TYPE_FLAGS:
2208
+ rb_raise(rb_eNotImpError,
2209
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2210
+ g_info_type_to_string(type),
2211
+ g_type_name(gtype));
2212
+ break;
2213
+ case GI_INFO_TYPE_OBJECT:
2214
+ case GI_INFO_TYPE_INTERFACE:
2215
+ g_slist_free_full(data->value->v_pointer, g_object_unref);
2216
+ break;
2217
+ case GI_INFO_TYPE_CONSTANT:
2218
+ case GI_INFO_TYPE_INVALID_0:
2219
+ case GI_INFO_TYPE_UNION:
2220
+ case GI_INFO_TYPE_VALUE:
2221
+ case GI_INFO_TYPE_SIGNAL:
2222
+ case GI_INFO_TYPE_VFUNC:
2223
+ case GI_INFO_TYPE_PROPERTY:
2224
+ case GI_INFO_TYPE_FIELD:
2225
+ case GI_INFO_TYPE_ARG:
2226
+ case GI_INFO_TYPE_TYPE:
2227
+ case GI_INFO_TYPE_UNRESOLVED:
2228
+ rb_raise(rb_eNotImpError,
2229
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2230
+ g_info_type_to_string(type),
2231
+ g_type_name(gtype));
2232
+ break;
2233
+ default:
2234
+ g_assert_not_reached();
2235
+ break;
2236
+ }
2237
+ }
2238
+
2239
+ static void
2240
+ rb_gi_arguments_convert_return_value_free_everything_gslist(
2241
+ ReturnValueToRubyData *data)
2242
+ {
2243
+ if (!data->value->v_pointer)
2244
+ return;
2245
+
2246
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
2247
+ switch (element_type_tag) {
2248
+ case GI_TYPE_TAG_VOID:
2249
+ case GI_TYPE_TAG_BOOLEAN:
2250
+ case GI_TYPE_TAG_INT8:
2251
+ case GI_TYPE_TAG_UINT8:
2252
+ case GI_TYPE_TAG_INT16:
2253
+ case GI_TYPE_TAG_UINT16:
2254
+ case GI_TYPE_TAG_INT32:
2255
+ case GI_TYPE_TAG_UINT32:
2256
+ case GI_TYPE_TAG_INT64:
2257
+ case GI_TYPE_TAG_UINT64:
2258
+ case GI_TYPE_TAG_FLOAT:
2259
+ case GI_TYPE_TAG_DOUBLE:
2260
+ case GI_TYPE_TAG_GTYPE:
2261
+ rb_raise(rb_eNotImpError,
2262
+ "TODO: free GIArgument(GSList)[%s] everything",
2263
+ g_type_tag_to_string(element_type_tag));
2264
+ break;
2265
+ case GI_TYPE_TAG_UTF8:
2266
+ case GI_TYPE_TAG_FILENAME:
2267
+ g_slist_free_full(data->value->v_pointer, g_free);
2268
+ break;
2269
+ case GI_TYPE_TAG_ARRAY:
2270
+ rb_raise(rb_eNotImpError,
2271
+ "TODO: free GIArgument(GSList)[%s] everything",
2272
+ g_type_tag_to_string(element_type_tag));
2273
+ break;
2274
+ case GI_TYPE_TAG_INTERFACE:
2275
+ rb_gi_arguments_convert_return_value_free_everything_gslist_interface(data);
2276
+ break;
2277
+ case GI_TYPE_TAG_GLIST:
2278
+ case GI_TYPE_TAG_GSLIST:
2279
+ case GI_TYPE_TAG_GHASH:
2280
+ case GI_TYPE_TAG_ERROR:
2281
+ case GI_TYPE_TAG_UNICHAR:
2282
+ rb_raise(rb_eNotImpError,
2283
+ "TODO: free GIArgument(GSList)[%s] everything",
2284
+ g_type_tag_to_string(element_type_tag));
2285
+ break;
2286
+ default:
2287
+ g_assert_not_reached();
2288
+ break;
2289
+ }
2290
+ }
2291
+
2292
+ static void
2293
+ rb_gi_arguments_convert_return_value_free_everything(ReturnValueToRubyData *data)
2294
+ {
2295
+ GITypeTag type_tag = data->metadata->type.tag;
2296
+ switch (type_tag) {
2297
+ case GI_TYPE_TAG_VOID:
2298
+ break;
2299
+ case GI_TYPE_TAG_BOOLEAN:
2300
+ case GI_TYPE_TAG_INT8:
2301
+ case GI_TYPE_TAG_UINT8:
2302
+ case GI_TYPE_TAG_INT16:
2303
+ case GI_TYPE_TAG_UINT16:
2304
+ case GI_TYPE_TAG_INT32:
2305
+ case GI_TYPE_TAG_UINT32:
2306
+ case GI_TYPE_TAG_INT64:
2307
+ case GI_TYPE_TAG_UINT64:
2308
+ case GI_TYPE_TAG_FLOAT:
2309
+ case GI_TYPE_TAG_DOUBLE:
2310
+ case GI_TYPE_TAG_GTYPE:
2311
+ rb_raise(rb_eNotImpError,
2312
+ "TODO: free GIArgument(%s) everything",
2313
+ g_type_tag_to_string(type_tag));
2314
+ break;
2315
+ case GI_TYPE_TAG_UTF8:
2316
+ g_free(data->value->v_string);
2317
+ break;
2318
+ case GI_TYPE_TAG_FILENAME:
2319
+ g_free(data->value->v_string);
2320
+ break;
2321
+ case GI_TYPE_TAG_ARRAY:
2322
+ rb_gi_arguments_convert_return_value_free_everything_array(data);
2323
+ break;
2324
+ case GI_TYPE_TAG_INTERFACE:
2325
+ rb_gi_arguments_convert_return_value_free_everything_interface(data);
2326
+ break;
2327
+ case GI_TYPE_TAG_GLIST:
2328
+ rb_gi_arguments_convert_return_value_free_everything_glist(data);
2329
+ break;
2330
+ case GI_TYPE_TAG_GSLIST:
2331
+ rb_gi_arguments_convert_return_value_free_everything_gslist(data);
2332
+ break;
2333
+ case GI_TYPE_TAG_GHASH:
2334
+ g_hash_table_unref(data->value->v_pointer);
2335
+ break;
2336
+ case GI_TYPE_TAG_ERROR:
2337
+ case GI_TYPE_TAG_UNICHAR:
2338
+ rb_raise(rb_eNotImpError,
2339
+ "TODO: free GIArgument(%s) everything",
2340
+ g_type_tag_to_string(type_tag));
2341
+ break;
2342
+ default:
2343
+ g_assert_not_reached();
2344
+ break;
2345
+ }
2346
+ }
2347
+
2348
+ static VALUE
2349
+ rb_gi_arguments_convert_return_value_ensure_body(VALUE user_data)
2350
+ {
2351
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
2352
+
2353
+ switch (g_callable_info_get_caller_owns(data->args->info)) {
2354
+ case GI_TRANSFER_NOTHING:
2355
+ break;
2356
+ case GI_TRANSFER_CONTAINER:
2357
+ rb_gi_arguments_convert_return_value_free_container(data);
2358
+ break;
2359
+ case GI_TRANSFER_EVERYTHING:
2360
+ rb_gi_arguments_convert_return_value_free_everything(data);
2361
+ break;
2362
+ default:
2363
+ g_assert_not_reached();
2364
+ break;
2365
+ }
2366
+
2367
+ return Qnil;
2368
+ }
2369
+
2370
+ static VALUE
2371
+ rb_gi_arguments_convert_return_value_ensure_ensure(VALUE user_data)
2372
+ {
2373
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
2374
+ rb_gi_arg_metadata_clear(data->metadata);
2375
+ return Qnil;
2376
+ }
2377
+
2378
+ static VALUE
2379
+ rb_gi_arguments_convert_return_value_ensure(VALUE user_data)
2380
+ {
2381
+ return rb_ensure(rb_gi_arguments_convert_return_value_ensure_body,
2382
+ user_data,
2383
+ rb_gi_arguments_convert_return_value_ensure_ensure,
2384
+ user_data);
2385
+ }
2386
+
2387
+ VALUE
2388
+ rb_gi_arguments_convert_return_value(RBGIArguments *args,
2389
+ GIArgument *return_value)
2390
+ {
2391
+ if (g_callable_info_may_return_null(args->info) &&
2392
+ !return_value->v_pointer) {
2393
+ GITypeInfo return_value_info;
2394
+ g_callable_info_load_return_type(args->info, &return_value_info);
2395
+ GITypeTag return_value_tag = g_type_info_get_tag(&return_value_info);
2396
+ switch (return_value_tag) {
2397
+ case GI_TYPE_TAG_GLIST:
2398
+ case GI_TYPE_TAG_GSLIST:
2399
+ return rb_ary_new();
2400
+ default:
2401
+ return Qnil;
2402
+ }
2403
+ }
2404
+
2405
+ ReturnValueToRubyData data;
2406
+ data.args = args;
2407
+ data.value = return_value;
2408
+ RBGIArgMetadata metadata;
2409
+ GITypeInfo *return_value_info = g_callable_info_get_return_type(args->info);
2410
+ rb_gi_arg_metadata_init_type_info(&metadata, return_value_info);
2411
+ data.metadata = &metadata;
2412
+
2413
+ return rb_ensure(rb_gi_arguments_convert_return_value_body, (VALUE)&data,
2414
+ rb_gi_arguments_convert_return_value_ensure, (VALUE)&data);
2415
+ }
2416
+
2417
+ void
2418
+ rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
2419
+ VALUE rb_error)
2420
+ {
2421
+ if (!g_callable_info_can_throw_gerror(args->info)) {
2422
+ return;
2423
+ }
2424
+
2425
+ gint n_args = g_callable_info_get_n_args(args->info);
2426
+ /* GError ** isn't listed in args. */
2427
+ GError **gerror = *((gpointer *)(args->raw_args[n_args]));
2428
+ VALUE cGLibErrorInfo = rb_const_get(rbg_mGLib(), rb_intern("ErrorInfo"));
2429
+ if (NIL_P(rb_error)) {
2430
+ g_set_error(gerror,
2431
+ RBG_RUBY_ERROR,
2432
+ RBG_RUBY_ERROR_UNKNOWN,
2433
+ "Unknown error");
2434
+ } else {
2435
+ VALUE message = rb_funcall(rb_error, rb_intern("message"), 0);
2436
+ VALUE backtrace = rb_funcall(rb_error, rb_intern("backtrace"), 0);
2437
+ VALUE formatted_backtrace =
2438
+ rb_ary_join(backtrace, rb_str_new_cstr(" \n"));
2439
+ GQuark gdomain = RBG_RUBY_ERROR;
2440
+ gint gcode = RBG_RUBY_ERROR_UNKNOWN;
2441
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_error, cGLibErrorInfo))) {
2442
+ VALUE domain = rb_funcall(rb_error, rb_intern("domain"), 0);
2443
+ VALUE code = rb_funcall(rb_error, rb_intern("code"), 0);
2444
+ if (!NIL_P(domain) && !NIL_P(code)) {
2445
+ gdomain = g_quark_from_string(RVAL2CSTR(domain));
2446
+ gcode = NUM2INT(code);
2447
+ }
2448
+ }
2449
+ g_set_error(gerror,
2450
+ gdomain,
2451
+ gcode,
2452
+ "%s\n %s\n",
2453
+ RVAL2CSTR(message),
2454
+ RVAL2CSTR(formatted_backtrace));
2455
+ }
2456
+ }
2457
+
2458
+ static void
2459
+ rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
2460
+ VALUE rb_result,
2461
+ gpointer raw_result,
2462
+ GITypeInfo *type_info,
2463
+ GITransfer transfer,
2464
+ gboolean is_return_value)
2465
+ {
2466
+ GIBaseInfo *interface_info;
2467
+ GIInfoType interface_type;
2468
+ GIFFIReturnValue *ffi_return_value = raw_result;
2469
+
2470
+ interface_info = g_type_info_get_interface(type_info);
2471
+ interface_type = g_base_info_get_type(interface_info);
2472
+
2473
+ switch (interface_type) {
2474
+ case GI_INFO_TYPE_INVALID:
2475
+ case GI_INFO_TYPE_FUNCTION:
2476
+ case GI_INFO_TYPE_CALLBACK:
2477
+ rb_raise(rb_eNotImpError,
2478
+ "TODO: %s::%s: out raw result(interface)[%s]: <%s>",
2479
+ args->namespace,
2480
+ args->name,
2481
+ g_info_type_to_string(interface_type),
2482
+ g_base_info_get_name(interface_info));
2483
+ break;
2484
+ case GI_INFO_TYPE_STRUCT:
2485
+ {
2486
+ gpointer value;
2487
+ GType gtype = g_registered_type_info_get_g_type(interface_info);
2488
+ if (gtype == G_TYPE_NONE) {
2489
+ /* Is it OK? */
2490
+ /* value = RVAL2GPTR(rb_result); */
2491
+ rb_raise(rb_eNotImpError,
2492
+ "TODO: %s::%s: out raw result(interface)[%s][%s]: <%s>",
2493
+ args->namespace,
2494
+ args->name,
2495
+ g_info_type_to_string(interface_type),
2496
+ g_type_name(gtype),
2497
+ g_base_info_get_name(interface_info));
2498
+ } else {
2499
+ value = RVAL2BOXED(rb_result, gtype);
2500
+ if (transfer == GI_TRANSFER_EVERYTHING) {
2501
+ value = g_boxed_copy(gtype, value);
2502
+ }
2503
+ }
2504
+ if (is_return_value) {
2505
+ ffi_return_value->v_pointer = value;
2506
+ } else {
2507
+ *((gpointer *)raw_result) = value;
2508
+ }
2509
+ }
2510
+ break;
561
2511
  case GI_INFO_TYPE_BOXED:
562
2512
  rb_raise(rb_eNotImpError,
563
2513
  "TODO: %s::%s: out raw result(interface)[%s]: <%s>",