gobject-introspection 3.4.9 → 3.5.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
+ static 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,6 +530,1828 @@ rb_gi_arguments_get_rb_out_args(RBGIArguments *args)
497
530
  return rb_gi_arguments_out_to_ruby(args);
498
531
  }
499
532
 
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)
543
+ {
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;
604
+ }
605
+ }
606
+
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
+ {
664
+ gconstpointer *elements = data->arg->v_pointer;
665
+ data->interface_type_info =
666
+ g_type_info_get_interface(data->element_type_info);
667
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
668
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
669
+ switch (type) {
670
+ case GI_INFO_TYPE_INVALID:
671
+ case GI_INFO_TYPE_FUNCTION:
672
+ case GI_INFO_TYPE_CALLBACK:
673
+ rb_raise(rb_eNotImpError,
674
+ "TODO: GIArgument(array)[c][interface(%s)](%s) -> Ruby",
675
+ g_info_type_to_string(type),
676
+ g_type_name(gtype));
677
+ return Qnil;
678
+ case GI_INFO_TYPE_STRUCT:
679
+ if (gtype == G_TYPE_NONE) {
680
+ VALUE rb_arg = rb_ary_new_capa(length);
681
+ gint64 i;
682
+ for (i = 0; i < length; i++) {
683
+ rb_ary_push(rb_arg,
684
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
685
+ (gpointer)elements[i],
686
+ TRUE));
687
+ }
688
+ return rb_arg;
689
+ } else {
690
+ /* TODO: Should we check caller_allocates? */
691
+ gsize struct_size =
692
+ g_struct_info_get_size(data->interface_type_info);
693
+ VALUE rb_arg = rb_ary_new_capa(length);
694
+ gint64 i;
695
+ for (i = 0; i < length; i++) {
696
+ gpointer element = ((gchar *)elements) + struct_size * i;
697
+ rb_ary_push(rb_arg, BOXED2RVAL(element, gtype));
698
+ }
699
+ return rb_arg;
700
+ }
701
+ case GI_INFO_TYPE_BOXED:
702
+ case GI_INFO_TYPE_ENUM:
703
+ case GI_INFO_TYPE_FLAGS:
704
+ rb_raise(rb_eNotImpError,
705
+ "TODO: GIArgument(array)[c][interface(%s)](%s) -> Ruby",
706
+ g_info_type_to_string(type),
707
+ g_type_name(gtype));
708
+ return Qnil;
709
+ case GI_INFO_TYPE_OBJECT:
710
+ {
711
+ VALUE rb_arg = rb_ary_new_capa(length);
712
+ gint64 i;
713
+ for (i = 0; i < length; i++) {
714
+ rb_ary_push(rb_arg, GOBJ2RVAL((GObject *)(elements[i])));
715
+ }
716
+ return rb_arg;
717
+ }
718
+ case GI_INFO_TYPE_INTERFACE:
719
+ case GI_INFO_TYPE_CONSTANT:
720
+ case GI_INFO_TYPE_INVALID_0:
721
+ case GI_INFO_TYPE_UNION:
722
+ case GI_INFO_TYPE_VALUE:
723
+ case GI_INFO_TYPE_SIGNAL:
724
+ case GI_INFO_TYPE_VFUNC:
725
+ case GI_INFO_TYPE_PROPERTY:
726
+ case GI_INFO_TYPE_FIELD:
727
+ case GI_INFO_TYPE_ARG:
728
+ case GI_INFO_TYPE_TYPE:
729
+ case GI_INFO_TYPE_UNRESOLVED:
730
+ rb_raise(rb_eNotImpError,
731
+ "TODO: GIArgument(array)[c][interface(%s)](%s) -> Ruby",
732
+ g_info_type_to_string(type),
733
+ g_type_name(gtype));
734
+ return Qnil;
735
+ default:
736
+ g_assert_not_reached();
737
+ return Qnil;
738
+ }
739
+ }
740
+
741
+ static VALUE
742
+ rb_gi_arguments_convert_arg_array_body_c_sized(ArrayLikeToRubyData *data,
743
+ gint64 length)
744
+ {
745
+ gconstpointer elements = data->arg->v_pointer;
746
+ switch (data->element_type_tag) {
747
+ case GI_TYPE_TAG_VOID:
748
+ rb_raise(rb_eNotImpError,
749
+ "TODO: GIArgument(array)[c][%s] -> Ruby",
750
+ g_type_tag_to_string(data->element_type_tag));
751
+ return Qnil;
752
+ case GI_TYPE_TAG_BOOLEAN:
753
+ {
754
+ const gboolean *booleans = (const gboolean *)elements;
755
+ VALUE rb_arg = rb_ary_new_capa(length);
756
+ gint64 i;
757
+ for (i = 0; i < length; i++) {
758
+ rb_ary_push(rb_arg, CBOOL2RVAL(booleans[i]));
759
+ }
760
+ return rb_arg;
761
+ }
762
+ case GI_TYPE_TAG_INT8:
763
+ {
764
+ const gint8 *numbers = (const gint8 *)elements;
765
+ VALUE rb_arg = rb_ary_new_capa(length);
766
+ gint64 i;
767
+ for (i = 0; i < length; i++) {
768
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
769
+ }
770
+ return rb_arg;
771
+ }
772
+ case GI_TYPE_TAG_UINT8:
773
+ if (data->arg_metadata->input_buffer_p) {
774
+ VALUE rb_arg = rb_str_new_static(elements, length);
775
+ rb_str_freeze(rb_arg);
776
+ return rb_arg;
777
+ } else {
778
+ const guint8 *numbers = (const guint8 *)elements;
779
+ VALUE rb_arg = rb_ary_new_capa(length);
780
+ gint64 i;
781
+ for (i = 0; i < length; i++) {
782
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
783
+ }
784
+ return rb_arg;
785
+ }
786
+ case GI_TYPE_TAG_INT16:
787
+ {
788
+ const gint16 *numbers = (const gint16 *)elements;
789
+ VALUE rb_arg = rb_ary_new_capa(length);
790
+ gint64 i;
791
+ for (i = 0; i < length; i++) {
792
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
793
+ }
794
+ return rb_arg;
795
+ }
796
+ case GI_TYPE_TAG_UINT16:
797
+ {
798
+ const guint16 *numbers = (const guint16 *)elements;
799
+ VALUE rb_arg = rb_ary_new_capa(length);
800
+ gint64 i;
801
+ for (i = 0; i < length; i++) {
802
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
803
+ }
804
+ return rb_arg;
805
+ }
806
+ case GI_TYPE_TAG_INT32:
807
+ {
808
+ const gint32 *numbers = (const gint32 *)elements;
809
+ VALUE rb_arg = rb_ary_new_capa(length);
810
+ gint64 i;
811
+ for (i = 0; i < length; i++) {
812
+ rb_ary_push(rb_arg, INT2NUM(numbers[i]));
813
+ }
814
+ return rb_arg;
815
+ }
816
+ case GI_TYPE_TAG_UINT32:
817
+ {
818
+ const guint32 *numbers = (const guint32 *)elements;
819
+ VALUE rb_arg = rb_ary_new_capa(length);
820
+ gint64 i;
821
+ for (i = 0; i < length; i++) {
822
+ rb_ary_push(rb_arg, UINT2NUM(numbers[i]));
823
+ }
824
+ return rb_arg;
825
+ }
826
+ case GI_TYPE_TAG_INT64:
827
+ {
828
+ const gint64 *numbers = (const gint64 *)elements;
829
+ VALUE rb_arg = rb_ary_new_capa(length);
830
+ gint64 i;
831
+ for (i = 0; i < length; i++) {
832
+ rb_ary_push(rb_arg, LL2NUM(numbers[i]));
833
+ }
834
+ return rb_arg;
835
+ }
836
+ case GI_TYPE_TAG_UINT64:
837
+ {
838
+ const guint64 *numbers = (const guint64 *)elements;
839
+ VALUE rb_arg = rb_ary_new_capa(length);
840
+ gint64 i;
841
+ for (i = 0; i < length; i++) {
842
+ rb_ary_push(rb_arg, ULL2NUM(numbers[i]));
843
+ }
844
+ return rb_arg;
845
+ }
846
+ case GI_TYPE_TAG_FLOAT:
847
+ {
848
+ const gfloat *numbers = (const gfloat *)elements;
849
+ VALUE rb_arg = rb_ary_new_capa(length);
850
+ gint64 i;
851
+ for (i = 0; i < length; i++) {
852
+ rb_ary_push(rb_arg, rb_float_new(numbers[i]));
853
+ }
854
+ return rb_arg;
855
+ }
856
+ case GI_TYPE_TAG_DOUBLE:
857
+ {
858
+ const gdouble *numbers = (const gdouble *)elements;
859
+ VALUE rb_arg = rb_ary_new_capa(length);
860
+ gint64 i;
861
+ for (i = 0; i < length; i++) {
862
+ rb_ary_push(rb_arg, rb_float_new(numbers[i]));
863
+ }
864
+ return rb_arg;
865
+ }
866
+ case GI_TYPE_TAG_GTYPE:
867
+ rb_raise(rb_eNotImpError,
868
+ "TODO: GIArgument(array)[c][%s] -> Ruby",
869
+ g_type_tag_to_string(data->element_type_tag));
870
+ return Qnil;
871
+ case GI_TYPE_TAG_UTF8:
872
+ {
873
+ const gchar **strings = (const gchar **)elements;
874
+ VALUE rb_arg = rb_ary_new_capa(length);
875
+ gint64 i;
876
+ for (i = 0; i < length; i++) {
877
+ rb_ary_push(rb_arg, CSTR2RVAL(strings[i]));
878
+ }
879
+ return rb_arg;
880
+ }
881
+ case GI_TYPE_TAG_FILENAME:
882
+ {
883
+ const gchar **filenames = (const gchar **)elements;
884
+ VALUE rb_arg = rb_ary_new_capa(length);
885
+ gint64 i;
886
+ for (i = 0; i < length; i++) {
887
+ rb_ary_push(rb_arg, CSTRFILENAME2RVAL(filenames[i]));
888
+ }
889
+ return rb_arg;
890
+ }
891
+ case GI_TYPE_TAG_ARRAY:
892
+ rb_raise(rb_eNotImpError,
893
+ "TODO: GIArgument(array)[c][%s] -> Ruby",
894
+ g_type_tag_to_string(data->element_type_tag));
895
+ return Qnil;
896
+ case GI_TYPE_TAG_INTERFACE:
897
+ return
898
+ rb_gi_arguments_convert_arg_array_body_c_sized_interface(data,
899
+ length);
900
+ case GI_TYPE_TAG_GLIST:
901
+ case GI_TYPE_TAG_GSLIST:
902
+ case GI_TYPE_TAG_GHASH:
903
+ case GI_TYPE_TAG_ERROR:
904
+ case GI_TYPE_TAG_UNICHAR:
905
+ rb_raise(rb_eNotImpError,
906
+ "TODO: GIArgument(array)[c][%s] -> Ruby",
907
+ g_type_tag_to_string(data->element_type_tag));
908
+ return Qnil;
909
+ default:
910
+ g_assert_not_reached();
911
+ return Qnil;
912
+ }
913
+ }
914
+
915
+ static VALUE
916
+ rb_gi_arguments_convert_arg_array_body_c(ArrayLikeToRubyData *data,
917
+ gint64 length)
918
+ {
919
+ gconstpointer *elements = data->arg->v_pointer;
920
+ if (!elements) {
921
+ return rb_ary_new();
922
+ }
923
+
924
+ GITypeInfo *type_info = data->arg_metadata->type_info;
925
+ gint fixed_size = g_type_info_get_array_fixed_size(type_info);
926
+ gboolean zero_terminated_p = g_type_info_is_zero_terminated(type_info);
927
+
928
+ if (length != -1) {
929
+ return rb_gi_arguments_convert_arg_array_body_c_sized(data, length);
930
+ } else if (zero_terminated_p) {
931
+ return STRV2RVAL((const gchar **)elements);
932
+ } else {
933
+ rb_raise(rb_eNotImpError,
934
+ "TODO: GIArgument(array)[c] -> Ruby: "
935
+ "zero-terminated: %s "
936
+ "fixed-size: %d "
937
+ "length: %" G_GINT64_FORMAT,
938
+ zero_terminated_p ? "true" : "false",
939
+ fixed_size,
940
+ length);
941
+ return Qnil;
942
+ }
943
+ }
944
+
945
+ static VALUE
946
+ rb_gi_arguments_convert_arg_array_body_array_interface(ArrayLikeToRubyData *data)
947
+ {
948
+ GArray *elements = data->arg->v_pointer;
949
+ data->interface_type_info =
950
+ g_type_info_get_interface(data->element_type_info);
951
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
952
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
953
+ switch (type) {
954
+ case GI_INFO_TYPE_INVALID:
955
+ case GI_INFO_TYPE_FUNCTION:
956
+ case GI_INFO_TYPE_CALLBACK:
957
+ rb_raise(rb_eNotImpError,
958
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
959
+ g_info_type_to_string(type),
960
+ g_type_name(gtype));
961
+ return Qnil;
962
+ case GI_INFO_TYPE_STRUCT:
963
+ if (gtype == G_TYPE_NONE) {
964
+ VALUE rb_arg = rb_ary_new_capa(elements->len);
965
+ guint element_size = g_array_get_element_size(elements);
966
+ guint i;
967
+ for (i = 0; i < elements->len; i++) {
968
+ gpointer element;
969
+ element = elements->data + (element_size * i);
970
+ rb_ary_push(rb_arg,
971
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
972
+ element,
973
+ FALSE));
974
+ }
975
+ return rb_arg;
976
+ } else {
977
+ rb_raise(rb_eNotImpError,
978
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
979
+ g_info_type_to_string(type),
980
+ g_type_name(gtype));
981
+ return Qnil;
982
+ }
983
+ case GI_INFO_TYPE_BOXED:
984
+ case GI_INFO_TYPE_ENUM:
985
+ case GI_INFO_TYPE_FLAGS:
986
+ case GI_INFO_TYPE_OBJECT:
987
+ case GI_INFO_TYPE_INTERFACE:
988
+ case GI_INFO_TYPE_CONSTANT:
989
+ case GI_INFO_TYPE_INVALID_0:
990
+ case GI_INFO_TYPE_UNION:
991
+ case GI_INFO_TYPE_VALUE:
992
+ case GI_INFO_TYPE_SIGNAL:
993
+ case GI_INFO_TYPE_VFUNC:
994
+ case GI_INFO_TYPE_PROPERTY:
995
+ case GI_INFO_TYPE_FIELD:
996
+ case GI_INFO_TYPE_ARG:
997
+ case GI_INFO_TYPE_TYPE:
998
+ case GI_INFO_TYPE_UNRESOLVED:
999
+ rb_raise(rb_eNotImpError,
1000
+ "TODO: GIArgument(array)[array][interface(%s)](%s) -> Ruby",
1001
+ g_info_type_to_string(type),
1002
+ g_type_name(gtype));
1003
+ return Qnil;
1004
+ default:
1005
+ g_assert_not_reached();
1006
+ return Qnil;
1007
+ }
1008
+ }
1009
+
1010
+ static VALUE
1011
+ rb_gi_arguments_convert_arg_array_body_array(ArrayLikeToRubyData *data)
1012
+ {
1013
+ GArray *elements = data->arg->v_pointer;
1014
+ if (!elements) {
1015
+ return Qnil;
1016
+ }
1017
+
1018
+ switch (data->element_type_tag) {
1019
+ case GI_TYPE_TAG_VOID:
1020
+ case GI_TYPE_TAG_BOOLEAN:
1021
+ case GI_TYPE_TAG_INT8:
1022
+ case GI_TYPE_TAG_UINT8:
1023
+ case GI_TYPE_TAG_INT16:
1024
+ case GI_TYPE_TAG_UINT16:
1025
+ case GI_TYPE_TAG_INT32:
1026
+ case GI_TYPE_TAG_UINT32:
1027
+ case GI_TYPE_TAG_INT64:
1028
+ case GI_TYPE_TAG_UINT64:
1029
+ case GI_TYPE_TAG_FLOAT:
1030
+ case GI_TYPE_TAG_DOUBLE:
1031
+ case GI_TYPE_TAG_GTYPE:
1032
+ case GI_TYPE_TAG_UTF8:
1033
+ case GI_TYPE_TAG_FILENAME:
1034
+ case GI_TYPE_TAG_ARRAY:
1035
+ rb_raise(rb_eNotImpError,
1036
+ "TODO: GIArgument(array)[array][%s] -> Ruby",
1037
+ g_type_tag_to_string(data->element_type_tag));
1038
+ return Qnil;
1039
+ case GI_TYPE_TAG_INTERFACE:
1040
+ return rb_gi_arguments_convert_arg_array_body_array_interface(data);
1041
+ case GI_TYPE_TAG_GLIST:
1042
+ case GI_TYPE_TAG_GSLIST:
1043
+ case GI_TYPE_TAG_GHASH:
1044
+ case GI_TYPE_TAG_ERROR:
1045
+ case GI_TYPE_TAG_UNICHAR:
1046
+ rb_raise(rb_eNotImpError,
1047
+ "TODO: GIArgument(array)[array][%s] -> Ruby",
1048
+ g_type_tag_to_string(data->element_type_tag));
1049
+ return Qnil;
1050
+ default:
1051
+ g_assert_not_reached();
1052
+ return Qnil;
1053
+ }
1054
+ }
1055
+
1056
+ static gint64
1057
+ rb_gi_arguments_convert_arg_array_body_extract_length(GIArgument *arg,
1058
+ RBGIArgMetadata *metadata,
1059
+ gboolean is_pointer)
1060
+ {
1061
+ switch (metadata->type.tag) {
1062
+ case GI_TYPE_TAG_VOID:
1063
+ case GI_TYPE_TAG_BOOLEAN:
1064
+ rb_raise(rb_eNotImpError,
1065
+ "TODO: invalid out array length argument?: <%s>",
1066
+ g_type_tag_to_string(metadata->type.tag));
1067
+ return -1;
1068
+ case GI_TYPE_TAG_INT8:
1069
+ if (is_pointer) {
1070
+ return *((gint8 *)arg->v_pointer);
1071
+ } else {
1072
+ return arg->v_int8;
1073
+ }
1074
+ case GI_TYPE_TAG_UINT8:
1075
+ if (is_pointer) {
1076
+ return *((guint8 *)arg->v_pointer);
1077
+ } else {
1078
+ return arg->v_uint8;
1079
+ }
1080
+ case GI_TYPE_TAG_INT16:
1081
+ if (is_pointer) {
1082
+ return *((gint16 *)arg->v_pointer);
1083
+ } else {
1084
+ return arg->v_int16;
1085
+ }
1086
+ case GI_TYPE_TAG_UINT16:
1087
+ if (is_pointer) {
1088
+ return *((guint16 *)arg->v_pointer);
1089
+ } else {
1090
+ return arg->v_uint16;
1091
+ }
1092
+ case GI_TYPE_TAG_INT32:
1093
+ if (is_pointer) {
1094
+ return *((gint32 *)arg->v_pointer);
1095
+ } else {
1096
+ return arg->v_int32;
1097
+ }
1098
+ case GI_TYPE_TAG_UINT32:
1099
+ if (is_pointer) {
1100
+ return *((guint32 *)arg->v_pointer);
1101
+ } else {
1102
+ return arg->v_uint32;
1103
+ }
1104
+ case GI_TYPE_TAG_INT64:
1105
+ if (is_pointer) {
1106
+ return *((gint64 *)arg->v_pointer);
1107
+ } else {
1108
+ return arg->v_int64;
1109
+ }
1110
+ case GI_TYPE_TAG_UINT64:
1111
+ if (is_pointer) {
1112
+ return *((guint64 *)arg->v_pointer);
1113
+ } else {
1114
+ return arg->v_uint64;
1115
+ }
1116
+ case GI_TYPE_TAG_FLOAT:
1117
+ case GI_TYPE_TAG_DOUBLE:
1118
+ case GI_TYPE_TAG_GTYPE:
1119
+ case GI_TYPE_TAG_UTF8:
1120
+ case GI_TYPE_TAG_FILENAME:
1121
+ case GI_TYPE_TAG_ARRAY:
1122
+ case GI_TYPE_TAG_INTERFACE:
1123
+ case GI_TYPE_TAG_GLIST:
1124
+ case GI_TYPE_TAG_GSLIST:
1125
+ case GI_TYPE_TAG_GHASH:
1126
+ case GI_TYPE_TAG_ERROR:
1127
+ case GI_TYPE_TAG_UNICHAR:
1128
+ rb_raise(rb_eNotImpError,
1129
+ "TODO: invalid out array length argument?: <%s>",
1130
+ g_type_tag_to_string(metadata->type.tag));
1131
+ return -1;
1132
+ default:
1133
+ g_assert_not_reached();
1134
+ return -1;
1135
+ }
1136
+ }
1137
+
1138
+ static VALUE
1139
+ rb_gi_arguments_convert_arg_array_body(VALUE user_data)
1140
+ {
1141
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1142
+ GITypeInfo *type_info = data->arg_metadata->type_info;
1143
+
1144
+ gint length_index = g_type_info_get_array_length(type_info);
1145
+ gint64 length = -1;
1146
+ if (length_index != -1) {
1147
+ GIArgument *length_arg = NULL;
1148
+ RBGIArgMetadata *length_metadata =
1149
+ g_ptr_array_index(data->args->metadata, length_index);
1150
+ if (length_metadata->direction == GI_DIRECTION_OUT) {
1151
+ length_arg = &g_array_index(data->args->out_args,
1152
+ GIArgument,
1153
+ length_metadata->out_arg_index);
1154
+ } else if (length_metadata->direction == GI_DIRECTION_INOUT) {
1155
+ length_arg = &g_array_index(data->args->in_args,
1156
+ GIArgument,
1157
+ length_metadata->in_arg_index);
1158
+ }
1159
+
1160
+ if (length_arg) {
1161
+ gboolean is_pointer =
1162
+ !(length_metadata->array_metadata &&
1163
+ length_metadata->array_metadata->output_buffer_p);
1164
+ length =
1165
+ rb_gi_arguments_convert_arg_array_body_extract_length(
1166
+ length_arg,
1167
+ length_metadata,
1168
+ is_pointer);
1169
+ } else {
1170
+ length_arg = &g_array_index(data->args->in_args,
1171
+ GIArgument,
1172
+ length_metadata->in_arg_index);
1173
+ length =
1174
+ rb_gi_arguments_convert_arg_array_body_extract_length(
1175
+ length_arg,
1176
+ length_metadata,
1177
+ FALSE);
1178
+ }
1179
+ }
1180
+
1181
+ GIArrayType array_type = g_type_info_get_array_type(type_info);
1182
+ switch (array_type) {
1183
+ case GI_ARRAY_TYPE_C:
1184
+ return rb_gi_arguments_convert_arg_array_body_c(data, length);
1185
+ case GI_ARRAY_TYPE_ARRAY:
1186
+ return rb_gi_arguments_convert_arg_array_body_array(data);
1187
+ case GI_ARRAY_TYPE_PTR_ARRAY:
1188
+ rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[ptr-array] -> Ruby");
1189
+ return Qnil;
1190
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
1191
+ rb_raise(rb_eNotImpError, "TODO: GIArgument(array)[byte-array] -> Ruby");
1192
+ return Qnil;
1193
+ default:
1194
+ g_assert_not_reached();
1195
+ return Qnil;
1196
+ }
1197
+ }
1198
+
1199
+ static VALUE
1200
+ rb_gi_arguments_convert_arg_array(RBGIArguments *args,
1201
+ GIArgument *arg,
1202
+ RBGIArgMetadata *arg_metadata)
1203
+ {
1204
+ ArrayLikeToRubyData data;
1205
+ data.args = args;
1206
+ data.arg = arg;
1207
+ data.arg_metadata = arg_metadata;
1208
+ data.element_type_info =
1209
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1210
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1211
+ data.interface_type_info = NULL;
1212
+ return rb_ensure(rb_gi_arguments_convert_arg_array_body,
1213
+ (VALUE)&data,
1214
+ rb_gi_arguments_convert_arg_array_like_ensure,
1215
+ (VALUE)&data);
1216
+ }
1217
+
1218
+ static VALUE
1219
+ rb_gi_arguments_convert_arg_glist_body_interface(ArrayLikeToRubyData *data)
1220
+ {
1221
+ data->interface_type_info =
1222
+ g_type_info_get_interface(data->element_type_info);
1223
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
1224
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
1225
+ switch (type) {
1226
+ case GI_INFO_TYPE_INVALID:
1227
+ case GI_INFO_TYPE_FUNCTION:
1228
+ case GI_INFO_TYPE_CALLBACK:
1229
+ rb_raise(rb_eNotImpError,
1230
+ "TODO: GIArgument(GList)[interface(%s)](%s) -> Ruby",
1231
+ g_info_type_to_string(type),
1232
+ g_type_name(gtype));
1233
+ return Qnil;
1234
+ case GI_INFO_TYPE_STRUCT:
1235
+ if (gtype == G_TYPE_NONE) {
1236
+ VALUE rb_arg = rb_ary_new();
1237
+ GList *node;
1238
+ for (node = data->arg->v_pointer; node; node = g_list_next(node)) {
1239
+ rb_ary_push(rb_arg,
1240
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
1241
+ node->data,
1242
+ TRUE));
1243
+ }
1244
+ return rb_arg;
1245
+ } else if (gtype == G_TYPE_VARIANT) {
1246
+ VALUE rb_arg = rb_ary_new();
1247
+ GList *node;
1248
+ for (node = data->arg->v_pointer; node; node = g_list_next(node)) {
1249
+ rb_ary_push(rb_arg, rbg_variant_to_ruby(node->data));
1250
+ }
1251
+ return rb_arg;
1252
+ } else {
1253
+ return BOXEDGLIST2RVAL(data->arg->v_pointer, gtype);
1254
+ }
1255
+ case GI_INFO_TYPE_BOXED:
1256
+ return BOXEDGLIST2RVAL(data->arg->v_pointer, gtype);
1257
+ case GI_INFO_TYPE_ENUM:
1258
+ case GI_INFO_TYPE_FLAGS:
1259
+ case GI_INFO_TYPE_OBJECT:
1260
+ case GI_INFO_TYPE_INTERFACE:
1261
+ return GOBJGLIST2RVAL(data->arg->v_pointer);
1262
+ case GI_INFO_TYPE_CONSTANT:
1263
+ case GI_INFO_TYPE_INVALID_0:
1264
+ case GI_INFO_TYPE_UNION:
1265
+ case GI_INFO_TYPE_VALUE:
1266
+ case GI_INFO_TYPE_SIGNAL:
1267
+ case GI_INFO_TYPE_VFUNC:
1268
+ case GI_INFO_TYPE_PROPERTY:
1269
+ case GI_INFO_TYPE_FIELD:
1270
+ case GI_INFO_TYPE_ARG:
1271
+ case GI_INFO_TYPE_TYPE:
1272
+ case GI_INFO_TYPE_UNRESOLVED:
1273
+ rb_raise(rb_eNotImpError,
1274
+ "TODO: GIArgument(GList)[interface(%s)](%s) -> Ruby",
1275
+ g_info_type_to_string(type),
1276
+ g_type_name(gtype));
1277
+ return Qnil;
1278
+ default:
1279
+ g_assert_not_reached();
1280
+ return Qnil;
1281
+ }
1282
+ }
1283
+
1284
+ static VALUE
1285
+ rb_gi_arguments_convert_arg_glist_body(VALUE user_data)
1286
+ {
1287
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1288
+
1289
+ switch (data->element_type_tag) {
1290
+ case GI_TYPE_TAG_VOID:
1291
+ case GI_TYPE_TAG_BOOLEAN:
1292
+ case GI_TYPE_TAG_INT8:
1293
+ case GI_TYPE_TAG_UINT8:
1294
+ case GI_TYPE_TAG_INT16:
1295
+ case GI_TYPE_TAG_UINT16:
1296
+ case GI_TYPE_TAG_INT32:
1297
+ case GI_TYPE_TAG_UINT32:
1298
+ case GI_TYPE_TAG_INT64:
1299
+ case GI_TYPE_TAG_UINT64:
1300
+ case GI_TYPE_TAG_FLOAT:
1301
+ case GI_TYPE_TAG_DOUBLE:
1302
+ case GI_TYPE_TAG_GTYPE:
1303
+ rb_raise(rb_eNotImpError,
1304
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1305
+ g_type_tag_to_string(data->element_type_tag));
1306
+ return Qnil;
1307
+ case GI_TYPE_TAG_UTF8:
1308
+ return CSTRGLIST2RVAL(data->arg->v_pointer);
1309
+ case GI_TYPE_TAG_FILENAME:
1310
+ return FILENAMEGLIST2RVAL(data->arg->v_pointer);
1311
+ case GI_TYPE_TAG_ARRAY:
1312
+ rb_raise(rb_eNotImpError,
1313
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1314
+ g_type_tag_to_string(data->element_type_tag));
1315
+ return Qnil;
1316
+ case GI_TYPE_TAG_INTERFACE:
1317
+ return rb_gi_arguments_convert_arg_glist_body_interface(data);
1318
+ case GI_TYPE_TAG_GLIST:
1319
+ case GI_TYPE_TAG_GSLIST:
1320
+ case GI_TYPE_TAG_GHASH:
1321
+ case GI_TYPE_TAG_ERROR:
1322
+ case GI_TYPE_TAG_UNICHAR:
1323
+ rb_raise(rb_eNotImpError,
1324
+ "TODO: GIArgument(GList)[%s] -> Ruby",
1325
+ g_type_tag_to_string(data->element_type_tag));
1326
+ return Qnil;
1327
+ default:
1328
+ g_assert_not_reached();
1329
+ return Qnil;
1330
+ }
1331
+ }
1332
+
1333
+ static VALUE
1334
+ rb_gi_arguments_convert_arg_glist(RBGIArguments *args,
1335
+ GIArgument *arg,
1336
+ RBGIArgMetadata *arg_metadata)
1337
+ {
1338
+ ArrayLikeToRubyData data;
1339
+ data.args = args;
1340
+ data.arg = arg;
1341
+ data.arg_metadata = arg_metadata;
1342
+ data.element_type_info =
1343
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1344
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1345
+ data.interface_type_info = NULL;
1346
+ return rb_ensure(rb_gi_arguments_convert_arg_glist_body,
1347
+ (VALUE)&data,
1348
+ rb_gi_arguments_convert_arg_array_like_ensure,
1349
+ (VALUE)&data);
1350
+ }
1351
+
1352
+ static VALUE
1353
+ rb_gi_arguments_convert_arg_gslist_body_interface(ArrayLikeToRubyData *data)
1354
+ {
1355
+ data->interface_type_info =
1356
+ g_type_info_get_interface(data->element_type_info);
1357
+ GIInfoType type = g_base_info_get_type(data->interface_type_info);
1358
+ GType gtype = g_registered_type_info_get_g_type(data->interface_type_info);
1359
+ switch (type) {
1360
+ case GI_INFO_TYPE_INVALID:
1361
+ case GI_INFO_TYPE_FUNCTION:
1362
+ case GI_INFO_TYPE_CALLBACK:
1363
+ rb_raise(rb_eNotImpError,
1364
+ "TODO: GIArgument(GSList)[interface(%s)](%s) -> Ruby",
1365
+ g_info_type_to_string(type),
1366
+ g_type_name(gtype));
1367
+ return Qnil;
1368
+ case GI_INFO_TYPE_STRUCT:
1369
+ if (gtype == G_TYPE_NONE) {
1370
+ VALUE rb_arg = rb_ary_new();
1371
+ GSList *node;
1372
+ for (node = data->arg->v_pointer; node; node = g_slist_next(node)) {
1373
+ rb_ary_push(rb_arg,
1374
+ rb_gi_struct_info_to_ruby(data->interface_type_info,
1375
+ node->data,
1376
+ TRUE));
1377
+ }
1378
+ return rb_arg;
1379
+ } else if (gtype == G_TYPE_VARIANT) {
1380
+ VALUE rb_arg = rb_ary_new();
1381
+ GSList *node;
1382
+ for (node = data->arg->v_pointer; node; node = g_slist_next(node)) {
1383
+ rb_ary_push(rb_arg, rbg_variant_to_ruby(node->data));
1384
+ }
1385
+ return rb_arg;
1386
+ } else {
1387
+ return BOXEDGSLIST2RVAL(data->arg->v_pointer, gtype);
1388
+ }
1389
+ case GI_INFO_TYPE_BOXED:
1390
+ return BOXEDGSLIST2RVAL(data->arg->v_pointer, gtype);
1391
+ case GI_INFO_TYPE_ENUM:
1392
+ case GI_INFO_TYPE_FLAGS:
1393
+ case GI_INFO_TYPE_OBJECT:
1394
+ case GI_INFO_TYPE_INTERFACE:
1395
+ return GOBJGSLIST2RVAL(data->arg->v_pointer);
1396
+ case GI_INFO_TYPE_CONSTANT:
1397
+ case GI_INFO_TYPE_INVALID_0:
1398
+ case GI_INFO_TYPE_UNION:
1399
+ case GI_INFO_TYPE_VALUE:
1400
+ case GI_INFO_TYPE_SIGNAL:
1401
+ case GI_INFO_TYPE_VFUNC:
1402
+ case GI_INFO_TYPE_PROPERTY:
1403
+ case GI_INFO_TYPE_FIELD:
1404
+ case GI_INFO_TYPE_ARG:
1405
+ case GI_INFO_TYPE_TYPE:
1406
+ case GI_INFO_TYPE_UNRESOLVED:
1407
+ rb_raise(rb_eNotImpError,
1408
+ "TODO: GIArgument(GSList)[interface(%s)](%s) -> Ruby",
1409
+ g_info_type_to_string(type),
1410
+ g_type_name(gtype));
1411
+ return Qnil;
1412
+ default:
1413
+ g_assert_not_reached();
1414
+ return Qnil;
1415
+ }
1416
+ }
1417
+
1418
+ static VALUE
1419
+ rb_gi_arguments_convert_arg_gslist_body(VALUE user_data)
1420
+ {
1421
+ ArrayLikeToRubyData *data = (ArrayLikeToRubyData *)user_data;
1422
+
1423
+ switch (data->element_type_tag) {
1424
+ case GI_TYPE_TAG_VOID:
1425
+ case GI_TYPE_TAG_BOOLEAN:
1426
+ case GI_TYPE_TAG_INT8:
1427
+ case GI_TYPE_TAG_UINT8:
1428
+ case GI_TYPE_TAG_INT16:
1429
+ case GI_TYPE_TAG_UINT16:
1430
+ case GI_TYPE_TAG_INT32:
1431
+ case GI_TYPE_TAG_UINT32:
1432
+ case GI_TYPE_TAG_INT64:
1433
+ case GI_TYPE_TAG_UINT64:
1434
+ case GI_TYPE_TAG_FLOAT:
1435
+ case GI_TYPE_TAG_DOUBLE:
1436
+ case GI_TYPE_TAG_GTYPE:
1437
+ rb_raise(rb_eNotImpError,
1438
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1439
+ g_type_tag_to_string(data->element_type_tag));
1440
+ return Qnil;
1441
+ case GI_TYPE_TAG_UTF8:
1442
+ return CSTRGSLIST2RVAL(data->arg->v_pointer);
1443
+ case GI_TYPE_TAG_FILENAME:
1444
+ return FILENAMEGSLIST2RVAL(data->arg->v_pointer);
1445
+ case GI_TYPE_TAG_ARRAY:
1446
+ rb_raise(rb_eNotImpError,
1447
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1448
+ g_type_tag_to_string(data->element_type_tag));
1449
+ return Qnil;
1450
+ case GI_TYPE_TAG_INTERFACE:
1451
+ return rb_gi_arguments_convert_arg_gslist_body_interface(data);
1452
+ case GI_TYPE_TAG_GLIST:
1453
+ case GI_TYPE_TAG_GSLIST:
1454
+ case GI_TYPE_TAG_GHASH:
1455
+ case GI_TYPE_TAG_ERROR:
1456
+ case GI_TYPE_TAG_UNICHAR:
1457
+ rb_raise(rb_eNotImpError,
1458
+ "TODO: GIArgument(GSList)[%s] -> Ruby",
1459
+ g_type_tag_to_string(data->element_type_tag));
1460
+ return Qnil;
1461
+ default:
1462
+ g_assert_not_reached();
1463
+ return Qnil;
1464
+ }
1465
+ }
1466
+
1467
+ static VALUE
1468
+ rb_gi_arguments_convert_arg_gslist(RBGIArguments *args,
1469
+ GIArgument *arg,
1470
+ RBGIArgMetadata *arg_metadata)
1471
+ {
1472
+ ArrayLikeToRubyData data;
1473
+ data.args = args;
1474
+ data.arg = arg;
1475
+ data.arg_metadata = arg_metadata;
1476
+ data.element_type_info =
1477
+ g_type_info_get_param_type(arg_metadata->type_info, 0);
1478
+ data.element_type_tag = g_type_info_get_tag(data.element_type_info);
1479
+ data.interface_type_info = NULL;
1480
+ return rb_ensure(rb_gi_arguments_convert_arg_gslist_body,
1481
+ (VALUE)&data,
1482
+ rb_gi_arguments_convert_arg_array_like_ensure,
1483
+ (VALUE)&data);
1484
+ }
1485
+
1486
+ typedef struct {
1487
+ RBGIArguments *args;
1488
+ GIArgument *arg;
1489
+ RBGIArgMetadata *arg_metadata;
1490
+ VALUE rb_table;
1491
+ RBGIArgMetadata *key_metadata;
1492
+ RBGIArgMetadata *value_metadata;
1493
+ } GHashToRubyData;
1494
+
1495
+ static void
1496
+ rb_gi_arguments_convert_arg_ghash_foreach_body(gpointer key,
1497
+ gpointer value,
1498
+ gpointer user_data)
1499
+ {
1500
+ GHashToRubyData *data = user_data;
1501
+ VALUE rb_key;
1502
+ VALUE rb_value;
1503
+
1504
+ switch (data->key_metadata->type.tag) {
1505
+ case GI_TYPE_TAG_VOID:
1506
+ case GI_TYPE_TAG_BOOLEAN:
1507
+ case GI_TYPE_TAG_INT8:
1508
+ case GI_TYPE_TAG_UINT8:
1509
+ case GI_TYPE_TAG_INT16:
1510
+ case GI_TYPE_TAG_UINT16:
1511
+ case GI_TYPE_TAG_INT32:
1512
+ case GI_TYPE_TAG_UINT32:
1513
+ case GI_TYPE_TAG_INT64:
1514
+ case GI_TYPE_TAG_UINT64:
1515
+ case GI_TYPE_TAG_FLOAT:
1516
+ case GI_TYPE_TAG_DOUBLE:
1517
+ case GI_TYPE_TAG_GTYPE:
1518
+ rb_raise(rb_eNotImpError,
1519
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1520
+ g_type_tag_to_string(data->key_metadata->type.tag),
1521
+ g_type_tag_to_string(data->value_metadata->type.tag));
1522
+ break;
1523
+ case GI_TYPE_TAG_UTF8:
1524
+ rb_key = CSTR2RVAL(key);
1525
+ break;
1526
+ case GI_TYPE_TAG_FILENAME:
1527
+ case GI_TYPE_TAG_ARRAY:
1528
+ rb_raise(rb_eNotImpError,
1529
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1530
+ g_type_tag_to_string(data->key_metadata->type.tag),
1531
+ g_type_tag_to_string(data->value_metadata->type.tag));
1532
+ break;
1533
+ case GI_TYPE_TAG_INTERFACE:
1534
+ {
1535
+ GIArgument key_arg;
1536
+ key_arg.v_pointer = key;
1537
+ rb_key = rb_gi_arguments_convert_arg_interface(data->args,
1538
+ &key_arg,
1539
+ data->key_metadata,
1540
+ FALSE);
1541
+ }
1542
+ break;
1543
+ case GI_TYPE_TAG_GLIST:
1544
+ case GI_TYPE_TAG_GSLIST:
1545
+ case GI_TYPE_TAG_GHASH:
1546
+ case GI_TYPE_TAG_ERROR:
1547
+ case GI_TYPE_TAG_UNICHAR:
1548
+ rb_raise(rb_eNotImpError,
1549
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1550
+ g_type_tag_to_string(data->key_metadata->type.tag),
1551
+ g_type_tag_to_string(data->value_metadata->type.tag));
1552
+ break;
1553
+ default:
1554
+ g_assert_not_reached();
1555
+ break;
1556
+ }
1557
+
1558
+ switch (data->value_metadata->type.tag) {
1559
+ case GI_TYPE_TAG_VOID:
1560
+ case GI_TYPE_TAG_BOOLEAN:
1561
+ case GI_TYPE_TAG_INT8:
1562
+ case GI_TYPE_TAG_UINT8:
1563
+ case GI_TYPE_TAG_INT16:
1564
+ case GI_TYPE_TAG_UINT16:
1565
+ case GI_TYPE_TAG_INT32:
1566
+ case GI_TYPE_TAG_UINT32:
1567
+ case GI_TYPE_TAG_INT64:
1568
+ case GI_TYPE_TAG_UINT64:
1569
+ case GI_TYPE_TAG_FLOAT:
1570
+ case GI_TYPE_TAG_DOUBLE:
1571
+ case GI_TYPE_TAG_GTYPE:
1572
+ rb_raise(rb_eNotImpError,
1573
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1574
+ g_type_tag_to_string(data->key_metadata->type.tag),
1575
+ g_type_tag_to_string(data->value_metadata->type.tag));
1576
+ break;
1577
+ case GI_TYPE_TAG_UTF8:
1578
+ rb_value = CSTR2RVAL(value);
1579
+ break;
1580
+ case GI_TYPE_TAG_FILENAME:
1581
+ case GI_TYPE_TAG_ARRAY:
1582
+ rb_raise(rb_eNotImpError,
1583
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1584
+ g_type_tag_to_string(data->key_metadata->type.tag),
1585
+ g_type_tag_to_string(data->value_metadata->type.tag));
1586
+ break;
1587
+ case GI_TYPE_TAG_INTERFACE:
1588
+ {
1589
+ GIArgument value_arg;
1590
+ value_arg.v_pointer = value;
1591
+ rb_value = rb_gi_arguments_convert_arg_interface(
1592
+ data->args,
1593
+ &value_arg,
1594
+ data->value_metadata,
1595
+ FALSE);
1596
+ }
1597
+ break;
1598
+ case GI_TYPE_TAG_GLIST:
1599
+ case GI_TYPE_TAG_GSLIST:
1600
+ case GI_TYPE_TAG_GHASH:
1601
+ case GI_TYPE_TAG_ERROR:
1602
+ case GI_TYPE_TAG_UNICHAR:
1603
+ rb_raise(rb_eNotImpError,
1604
+ "TODO: GIArgument(GHash)[%s][%s] -> Ruby",
1605
+ g_type_tag_to_string(data->key_metadata->type.tag),
1606
+ g_type_tag_to_string(data->value_metadata->type.tag));
1607
+ break;
1608
+ default:
1609
+ g_assert_not_reached();
1610
+ break;
1611
+ }
1612
+
1613
+ rb_hash_aset(data->rb_table, rb_key, rb_value);
1614
+ }
1615
+
1616
+ static VALUE
1617
+ rb_gi_arguments_convert_arg_ghash_body(VALUE user_data)
1618
+ {
1619
+ GHashToRubyData *data = (GHashToRubyData *)user_data;
1620
+ g_hash_table_foreach(data->arg->v_pointer,
1621
+ rb_gi_arguments_convert_arg_ghash_foreach_body,
1622
+ data);
1623
+ return data->rb_table;
1624
+ }
1625
+
1626
+ static VALUE
1627
+ rb_gi_arguments_convert_arg_ghash_ensure(VALUE user_data)
1628
+ {
1629
+ GHashToRubyData *data = (GHashToRubyData *)user_data;
1630
+ rb_gi_arg_metadata_clear(data->key_metadata);
1631
+ rb_gi_arg_metadata_clear(data->value_metadata);
1632
+ return Qnil;
1633
+ }
1634
+
1635
+ static VALUE
1636
+ rb_gi_arguments_convert_arg_ghash(RBGIArguments *args,
1637
+ GIArgument *arg,
1638
+ RBGIArgMetadata *arg_metadata)
1639
+ {
1640
+ GHashToRubyData data;
1641
+
1642
+ data.args = args;
1643
+ data.arg = arg;
1644
+ data.arg_metadata = arg_metadata;
1645
+ data.rb_table = rb_hash_new();
1646
+
1647
+ GITypeInfo *type_info = arg_metadata->type_info;
1648
+
1649
+ RBGIArgMetadata key_metadata;
1650
+ rb_gi_arg_metadata_init_type_info(&key_metadata,
1651
+ g_type_info_get_param_type(type_info, 0));
1652
+ data.key_metadata = &key_metadata;
1653
+
1654
+ RBGIArgMetadata value_metadata;
1655
+ rb_gi_arg_metadata_init_type_info(&value_metadata,
1656
+ g_type_info_get_param_type(type_info, 1));
1657
+ data.value_metadata = &value_metadata;
1658
+
1659
+ return rb_ensure(rb_gi_arguments_convert_arg_ghash_body, (VALUE)&data,
1660
+ rb_gi_arguments_convert_arg_ghash_ensure, (VALUE)&data);
1661
+ }
1662
+
1663
+ static VALUE
1664
+ rb_gi_arguments_convert_arg_unichar(RBGIArguments *args,
1665
+ GIArgument *arg,
1666
+ RBGIArgMetadata *arg_metadata)
1667
+ {
1668
+ GError *error = NULL;
1669
+ gunichar ucs4_character = arg->v_uint32;
1670
+ gchar *utf8_string = g_ucs4_to_utf8(&ucs4_character, 1, NULL, NULL, &error);
1671
+ if (error) {
1672
+ RG_RAISE_ERROR(error);
1673
+ }
1674
+ return CSTR2RVAL_FREE(utf8_string);
1675
+ }
1676
+
1677
+ VALUE
1678
+ rb_gi_arguments_convert_arg(RBGIArguments *args,
1679
+ GIArgument *arg,
1680
+ RBGIArgMetadata *arg_metadata,
1681
+ gboolean duplicate)
1682
+ {
1683
+ GITypeTag type_tag = g_type_info_get_tag(arg_metadata->type_info);
1684
+ switch (type_tag) {
1685
+ case GI_TYPE_TAG_VOID:
1686
+ if (g_type_info_is_pointer(arg_metadata->type_info)) {
1687
+ return ULL2NUM((guint64)(arg->v_pointer));
1688
+ } else {
1689
+ return Qnil;
1690
+ }
1691
+ case GI_TYPE_TAG_BOOLEAN:
1692
+ return CBOOL2RVAL(arg->v_boolean);
1693
+ case GI_TYPE_TAG_INT8:
1694
+ return INT2NUM(arg->v_int8);
1695
+ case GI_TYPE_TAG_UINT8:
1696
+ return UINT2NUM(arg->v_uint8);
1697
+ case GI_TYPE_TAG_INT16:
1698
+ return INT2NUM(arg->v_int16);
1699
+ case GI_TYPE_TAG_UINT16:
1700
+ return UINT2NUM(arg->v_uint16);
1701
+ case GI_TYPE_TAG_INT32:
1702
+ return INT2NUM(arg->v_int32);
1703
+ case GI_TYPE_TAG_UINT32:
1704
+ return UINT2NUM(arg->v_uint32);
1705
+ case GI_TYPE_TAG_INT64:
1706
+ return LL2NUM(arg->v_int64);
1707
+ case GI_TYPE_TAG_UINT64:
1708
+ return ULL2NUM(arg->v_uint64);
1709
+ case GI_TYPE_TAG_FLOAT:
1710
+ return DBL2NUM(arg->v_float);
1711
+ case GI_TYPE_TAG_DOUBLE:
1712
+ return DBL2NUM(arg->v_double);
1713
+ case GI_TYPE_TAG_GTYPE:
1714
+ if (arg->v_size == G_TYPE_INVALID) {
1715
+ return Qnil;
1716
+ } else {
1717
+ return rbgobj_gtype_new(arg->v_size);
1718
+ }
1719
+ case GI_TYPE_TAG_UTF8:
1720
+ return CSTR2RVAL(arg->v_string);
1721
+ case GI_TYPE_TAG_FILENAME:
1722
+ return CSTRFILENAME2RVAL(arg->v_string);
1723
+ case GI_TYPE_TAG_ARRAY:
1724
+ return rb_gi_arguments_convert_arg_array(args, arg, arg_metadata);
1725
+ case GI_TYPE_TAG_INTERFACE:
1726
+ return rb_gi_arguments_convert_arg_interface(args,
1727
+ arg,
1728
+ arg_metadata,
1729
+ duplicate);
1730
+ case GI_TYPE_TAG_GLIST:
1731
+ return rb_gi_arguments_convert_arg_glist(args, arg, arg_metadata);
1732
+ case GI_TYPE_TAG_GSLIST:
1733
+ return rb_gi_arguments_convert_arg_gslist(args, arg, arg_metadata);
1734
+ case GI_TYPE_TAG_GHASH:
1735
+ return rb_gi_arguments_convert_arg_ghash(args, arg, arg_metadata);
1736
+ case GI_TYPE_TAG_ERROR:
1737
+ return GERROR2RVAL(arg->v_pointer);
1738
+ case GI_TYPE_TAG_UNICHAR:
1739
+ return rb_gi_arguments_convert_arg_unichar(args, arg, arg_metadata);
1740
+ default:
1741
+ g_assert_not_reached();
1742
+ return Qnil;
1743
+ }
1744
+ }
1745
+
1746
+ typedef struct {
1747
+ RBGIArguments *args;
1748
+ GIArgument *value;
1749
+ RBGIArgMetadata *metadata;
1750
+ } ReturnValueToRubyData;
1751
+
1752
+ static VALUE
1753
+ rb_gi_arguments_convert_return_value_body(VALUE user_data)
1754
+ {
1755
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
1756
+ return rb_gi_arguments_convert_arg(data->args,
1757
+ data->value,
1758
+ data->metadata,
1759
+ FALSE);
1760
+ }
1761
+
1762
+ static void
1763
+ rb_gi_arguments_convert_return_value_free_container(ReturnValueToRubyData *data)
1764
+ {
1765
+ GITypeTag type_tag = data->metadata->type.tag;
1766
+ switch (type_tag) {
1767
+ case GI_TYPE_TAG_VOID:
1768
+ case GI_TYPE_TAG_BOOLEAN:
1769
+ case GI_TYPE_TAG_INT8:
1770
+ case GI_TYPE_TAG_UINT8:
1771
+ case GI_TYPE_TAG_INT16:
1772
+ case GI_TYPE_TAG_UINT16:
1773
+ case GI_TYPE_TAG_INT32:
1774
+ case GI_TYPE_TAG_UINT32:
1775
+ case GI_TYPE_TAG_INT64:
1776
+ case GI_TYPE_TAG_UINT64:
1777
+ case GI_TYPE_TAG_FLOAT:
1778
+ case GI_TYPE_TAG_DOUBLE:
1779
+ case GI_TYPE_TAG_GTYPE:
1780
+ case GI_TYPE_TAG_UTF8:
1781
+ case GI_TYPE_TAG_FILENAME:
1782
+ rb_raise(rb_eNotImpError,
1783
+ "TODO: free GIArgument(%s) as container",
1784
+ g_type_tag_to_string(type_tag));
1785
+ break;
1786
+ case GI_TYPE_TAG_ARRAY:
1787
+ g_free(data->value->v_pointer);
1788
+ break;
1789
+ case GI_TYPE_TAG_INTERFACE:
1790
+ rb_raise(rb_eNotImpError,
1791
+ "TODO: free GIArgument(%s) as container",
1792
+ g_type_tag_to_string(type_tag));
1793
+ break;
1794
+ case GI_TYPE_TAG_GLIST:
1795
+ g_list_free(data->value->v_pointer);
1796
+ break;
1797
+ case GI_TYPE_TAG_GSLIST:
1798
+ g_slist_free(data->value->v_pointer);
1799
+ break;
1800
+ case GI_TYPE_TAG_GHASH:
1801
+ g_hash_table_unref(data->value->v_pointer);
1802
+ break;
1803
+ case GI_TYPE_TAG_ERROR:
1804
+ case GI_TYPE_TAG_UNICHAR:
1805
+ rb_raise(rb_eNotImpError,
1806
+ "TODO: free GIArgument(%s) as container",
1807
+ g_type_tag_to_string(type_tag));
1808
+ break;
1809
+ default:
1810
+ g_assert_not_reached();
1811
+ break;
1812
+ }
1813
+ }
1814
+
1815
+ static void
1816
+ rb_gi_arguments_convert_return_value_free_everything_array_c(
1817
+ ReturnValueToRubyData *data)
1818
+ {
1819
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
1820
+ switch (element_type_tag) {
1821
+ case GI_TYPE_TAG_VOID:
1822
+ rb_raise(rb_eNotImpError,
1823
+ "TODO: free GIArgument(array)[c][%s] everything",
1824
+ g_type_tag_to_string(element_type_tag));
1825
+ break;
1826
+ case GI_TYPE_TAG_BOOLEAN:
1827
+ case GI_TYPE_TAG_INT8:
1828
+ case GI_TYPE_TAG_UINT8:
1829
+ case GI_TYPE_TAG_INT16:
1830
+ case GI_TYPE_TAG_UINT16:
1831
+ case GI_TYPE_TAG_INT32:
1832
+ case GI_TYPE_TAG_UINT32:
1833
+ case GI_TYPE_TAG_INT64:
1834
+ case GI_TYPE_TAG_UINT64:
1835
+ case GI_TYPE_TAG_FLOAT:
1836
+ case GI_TYPE_TAG_DOUBLE:
1837
+ g_free(data->value->v_pointer);
1838
+ break;
1839
+ case GI_TYPE_TAG_GTYPE:
1840
+ rb_raise(rb_eNotImpError,
1841
+ "TODO: free GIArgument(array)[c][%s] everything",
1842
+ g_type_tag_to_string(element_type_tag));
1843
+ break;
1844
+ case GI_TYPE_TAG_UTF8:
1845
+ g_strfreev(data->value->v_pointer);
1846
+ break;
1847
+ case GI_TYPE_TAG_FILENAME:
1848
+ g_strfreev(data->value->v_pointer);
1849
+ break;
1850
+ case GI_TYPE_TAG_ARRAY:
1851
+ case GI_TYPE_TAG_INTERFACE:
1852
+ case GI_TYPE_TAG_GLIST:
1853
+ case GI_TYPE_TAG_GSLIST:
1854
+ case GI_TYPE_TAG_GHASH:
1855
+ case GI_TYPE_TAG_ERROR:
1856
+ case GI_TYPE_TAG_UNICHAR:
1857
+ rb_raise(rb_eNotImpError,
1858
+ "TODO: free GIArgument(array)[c][%s] everything",
1859
+ g_type_tag_to_string(element_type_tag));
1860
+ break;
1861
+ default:
1862
+ g_assert_not_reached();
1863
+ break;
1864
+ }
1865
+ }
1866
+
1867
+ static void
1868
+ rb_gi_arguments_convert_return_value_free_everything_array(
1869
+ ReturnValueToRubyData *data)
1870
+ {
1871
+ switch (data->metadata->array_type) {
1872
+ case GI_ARRAY_TYPE_C:
1873
+ rb_gi_arguments_convert_return_value_free_everything_array_c(data);
1874
+ break;
1875
+ case GI_ARRAY_TYPE_ARRAY:
1876
+ g_array_free(data->value->v_pointer, TRUE);
1877
+ break;
1878
+ case GI_ARRAY_TYPE_PTR_ARRAY:
1879
+ g_ptr_array_free(data->value->v_pointer, TRUE);
1880
+ break;
1881
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
1882
+ g_byte_array_free(data->value->v_pointer, TRUE);
1883
+ break;
1884
+ default:
1885
+ g_assert_not_reached();
1886
+ break;
1887
+ }
1888
+ }
1889
+
1890
+ static void
1891
+ rb_gi_arguments_convert_return_value_free_everything_interface(
1892
+ ReturnValueToRubyData *data)
1893
+ {
1894
+ if (!data->value->v_pointer) {
1895
+ return;
1896
+ }
1897
+
1898
+ GIInfoType type = data->metadata->type.interface_type;
1899
+ GType gtype = data->metadata->type.interface_gtype;
1900
+ switch (type) {
1901
+ case GI_INFO_TYPE_INVALID:
1902
+ case GI_INFO_TYPE_FUNCTION:
1903
+ case GI_INFO_TYPE_CALLBACK:
1904
+ rb_raise(rb_eNotImpError,
1905
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1906
+ g_info_type_to_string(type),
1907
+ g_type_name(gtype));
1908
+ break;
1909
+ case GI_INFO_TYPE_STRUCT:
1910
+ if (gtype == G_TYPE_INVALID) {
1911
+ xfree(data->value->v_pointer);
1912
+ } else if (gtype == G_TYPE_VARIANT) {
1913
+ g_variant_unref(data->value->v_pointer);
1914
+ } else {
1915
+ if (G_TYPE_IS_BOXED(gtype)) {
1916
+ g_boxed_free(gtype, data->value->v_pointer);
1917
+ } else {
1918
+ rbgobj_instance_unref(data->value->v_pointer);
1919
+ }
1920
+ }
1921
+ break;
1922
+ case GI_INFO_TYPE_BOXED:
1923
+ case GI_INFO_TYPE_ENUM:
1924
+ case GI_INFO_TYPE_FLAGS:
1925
+ rb_raise(rb_eNotImpError,
1926
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1927
+ g_info_type_to_string(type),
1928
+ g_type_name(gtype));
1929
+ break;
1930
+ case GI_INFO_TYPE_OBJECT:
1931
+ {
1932
+ GObject *object = data->value->v_pointer;
1933
+ if (g_object_is_floating(object)) {
1934
+ g_object_ref_sink(object);
1935
+ }
1936
+ g_object_unref(object);
1937
+ }
1938
+ break;
1939
+ case GI_INFO_TYPE_INTERFACE:
1940
+ g_object_unref(data->value->v_pointer);
1941
+ break;
1942
+ case GI_INFO_TYPE_CONSTANT:
1943
+ rb_raise(rb_eNotImpError,
1944
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1945
+ g_info_type_to_string(type),
1946
+ g_type_name(gtype));
1947
+ break;
1948
+ case GI_INFO_TYPE_INVALID_0:
1949
+ g_assert_not_reached();
1950
+ break;
1951
+ case GI_INFO_TYPE_UNION:
1952
+ if (gtype == G_TYPE_NONE) {
1953
+ rb_raise(rb_eNotImpError,
1954
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1955
+ g_info_type_to_string(type),
1956
+ g_type_name(gtype));
1957
+ } else {
1958
+ g_boxed_free(gtype, data->value->v_pointer);
1959
+ }
1960
+ break;
1961
+ case GI_INFO_TYPE_VALUE:
1962
+ case GI_INFO_TYPE_SIGNAL:
1963
+ case GI_INFO_TYPE_VFUNC:
1964
+ case GI_INFO_TYPE_PROPERTY:
1965
+ case GI_INFO_TYPE_FIELD:
1966
+ case GI_INFO_TYPE_ARG:
1967
+ case GI_INFO_TYPE_TYPE:
1968
+ case GI_INFO_TYPE_UNRESOLVED:
1969
+ rb_raise(rb_eNotImpError,
1970
+ "TODO: free GIArgument(interface(%s))(%s) everything",
1971
+ g_info_type_to_string(type),
1972
+ g_type_name(gtype));
1973
+ break;
1974
+ default:
1975
+ g_assert_not_reached();
1976
+ break;
1977
+ }
1978
+ }
1979
+
1980
+ static void
1981
+ rb_gi_boxed_free_callback(gpointer boxed, gpointer user_data)
1982
+ {
1983
+ GType *gtype = user_data;
1984
+ g_boxed_free(*gtype, boxed);
1985
+ }
1986
+
1987
+ static void
1988
+ rb_gi_arguments_convert_return_value_free_everything_glist_interface(
1989
+ ReturnValueToRubyData *data)
1990
+ {
1991
+ GIInfoType type = data->metadata->element_type.interface_type;
1992
+ GType gtype = data->metadata->element_type.interface_gtype;
1993
+ switch (type) {
1994
+ case GI_INFO_TYPE_INVALID:
1995
+ case GI_INFO_TYPE_FUNCTION:
1996
+ case GI_INFO_TYPE_CALLBACK:
1997
+ rb_raise(rb_eNotImpError,
1998
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
1999
+ g_info_type_to_string(type),
2000
+ g_type_name(gtype));
2001
+ break;
2002
+ case GI_INFO_TYPE_STRUCT:
2003
+ if (gtype == G_TYPE_NONE) {
2004
+ rb_raise(rb_eNotImpError,
2005
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2006
+ g_info_type_to_string(type),
2007
+ g_type_name(gtype));
2008
+ } else if (gtype == G_TYPE_VARIANT) {
2009
+ g_list_free_full(data->value->v_pointer,
2010
+ (GDestroyNotify)g_variant_unref);
2011
+ } else {
2012
+ g_list_foreach(data->value->v_pointer,
2013
+ rb_gi_boxed_free_callback,
2014
+ &gtype);
2015
+ g_list_free(data->value->v_pointer);
2016
+ }
2017
+ break;
2018
+ case GI_INFO_TYPE_BOXED:
2019
+ g_list_foreach(data->value->v_pointer,
2020
+ rb_gi_boxed_free_callback,
2021
+ &gtype);
2022
+ g_list_free(data->value->v_pointer);
2023
+ break;
2024
+ case GI_INFO_TYPE_ENUM:
2025
+ case GI_INFO_TYPE_FLAGS:
2026
+ rb_raise(rb_eNotImpError,
2027
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2028
+ g_info_type_to_string(type),
2029
+ g_type_name(gtype));
2030
+ break;
2031
+ case GI_INFO_TYPE_OBJECT:
2032
+ case GI_INFO_TYPE_INTERFACE:
2033
+ g_list_free_full(data->value->v_pointer, g_object_unref);
2034
+ break;
2035
+ case GI_INFO_TYPE_CONSTANT:
2036
+ case GI_INFO_TYPE_INVALID_0:
2037
+ case GI_INFO_TYPE_UNION:
2038
+ case GI_INFO_TYPE_VALUE:
2039
+ case GI_INFO_TYPE_SIGNAL:
2040
+ case GI_INFO_TYPE_VFUNC:
2041
+ case GI_INFO_TYPE_PROPERTY:
2042
+ case GI_INFO_TYPE_FIELD:
2043
+ case GI_INFO_TYPE_ARG:
2044
+ case GI_INFO_TYPE_TYPE:
2045
+ case GI_INFO_TYPE_UNRESOLVED:
2046
+ rb_raise(rb_eNotImpError,
2047
+ "TODO: free GIArgument(GList)[interface(%s)](%s) everything",
2048
+ g_info_type_to_string(type),
2049
+ g_type_name(gtype));
2050
+ break;
2051
+ default:
2052
+ g_assert_not_reached();
2053
+ break;
2054
+ }
2055
+ }
2056
+
2057
+ static void
2058
+ rb_gi_arguments_convert_return_value_free_everything_glist(
2059
+ ReturnValueToRubyData *data)
2060
+ {
2061
+ if (!data->value->v_pointer)
2062
+ return;
2063
+
2064
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
2065
+ switch (element_type_tag) {
2066
+ case GI_TYPE_TAG_VOID:
2067
+ case GI_TYPE_TAG_BOOLEAN:
2068
+ case GI_TYPE_TAG_INT8:
2069
+ case GI_TYPE_TAG_UINT8:
2070
+ case GI_TYPE_TAG_INT16:
2071
+ case GI_TYPE_TAG_UINT16:
2072
+ case GI_TYPE_TAG_INT32:
2073
+ case GI_TYPE_TAG_UINT32:
2074
+ case GI_TYPE_TAG_INT64:
2075
+ case GI_TYPE_TAG_UINT64:
2076
+ case GI_TYPE_TAG_FLOAT:
2077
+ case GI_TYPE_TAG_DOUBLE:
2078
+ case GI_TYPE_TAG_GTYPE:
2079
+ rb_raise(rb_eNotImpError,
2080
+ "TODO: free GIArgument(GList)[%s] everything",
2081
+ g_type_tag_to_string(element_type_tag));
2082
+ break;
2083
+ case GI_TYPE_TAG_UTF8:
2084
+ case GI_TYPE_TAG_FILENAME:
2085
+ g_list_free_full(data->value->v_pointer, g_free);
2086
+ break;
2087
+ case GI_TYPE_TAG_ARRAY:
2088
+ rb_raise(rb_eNotImpError,
2089
+ "TODO: free GIArgument(GList)[%s] everything",
2090
+ g_type_tag_to_string(element_type_tag));
2091
+ break;
2092
+ case GI_TYPE_TAG_INTERFACE:
2093
+ rb_gi_arguments_convert_return_value_free_everything_glist_interface(data);
2094
+ break;
2095
+ case GI_TYPE_TAG_GLIST:
2096
+ case GI_TYPE_TAG_GSLIST:
2097
+ case GI_TYPE_TAG_GHASH:
2098
+ case GI_TYPE_TAG_ERROR:
2099
+ case GI_TYPE_TAG_UNICHAR:
2100
+ rb_raise(rb_eNotImpError,
2101
+ "TODO: free GIArgument(GList)[%s] everything",
2102
+ g_type_tag_to_string(element_type_tag));
2103
+ break;
2104
+ default:
2105
+ g_assert_not_reached();
2106
+ break;
2107
+ }
2108
+ }
2109
+
2110
+ static void
2111
+ rb_gi_arguments_convert_return_value_free_everything_gslist_interface(
2112
+ ReturnValueToRubyData *data)
2113
+ {
2114
+ GIInfoType type = data->metadata->element_type.interface_type;
2115
+ GType gtype = data->metadata->element_type.interface_gtype;
2116
+ switch (type) {
2117
+ case GI_INFO_TYPE_INVALID:
2118
+ case GI_INFO_TYPE_FUNCTION:
2119
+ case GI_INFO_TYPE_CALLBACK:
2120
+ rb_raise(rb_eNotImpError,
2121
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2122
+ g_info_type_to_string(type),
2123
+ g_type_name(gtype));
2124
+ break;
2125
+ case GI_INFO_TYPE_STRUCT:
2126
+ if (gtype == G_TYPE_NONE) {
2127
+ rb_raise(rb_eNotImpError,
2128
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2129
+ g_info_type_to_string(type),
2130
+ g_type_name(gtype));
2131
+ } else {
2132
+ g_slist_foreach(data->value->v_pointer,
2133
+ rb_gi_boxed_free_callback,
2134
+ &gtype);
2135
+ g_slist_free(data->value->v_pointer);
2136
+ }
2137
+ break;
2138
+ case GI_INFO_TYPE_BOXED:
2139
+ g_slist_foreach(data->value->v_pointer,
2140
+ rb_gi_boxed_free_callback,
2141
+ &gtype);
2142
+ g_slist_free(data->value->v_pointer);
2143
+ break;
2144
+ case GI_INFO_TYPE_ENUM:
2145
+ case GI_INFO_TYPE_FLAGS:
2146
+ rb_raise(rb_eNotImpError,
2147
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2148
+ g_info_type_to_string(type),
2149
+ g_type_name(gtype));
2150
+ break;
2151
+ case GI_INFO_TYPE_OBJECT:
2152
+ case GI_INFO_TYPE_INTERFACE:
2153
+ g_slist_free_full(data->value->v_pointer, g_object_unref);
2154
+ break;
2155
+ case GI_INFO_TYPE_CONSTANT:
2156
+ case GI_INFO_TYPE_INVALID_0:
2157
+ case GI_INFO_TYPE_UNION:
2158
+ case GI_INFO_TYPE_VALUE:
2159
+ case GI_INFO_TYPE_SIGNAL:
2160
+ case GI_INFO_TYPE_VFUNC:
2161
+ case GI_INFO_TYPE_PROPERTY:
2162
+ case GI_INFO_TYPE_FIELD:
2163
+ case GI_INFO_TYPE_ARG:
2164
+ case GI_INFO_TYPE_TYPE:
2165
+ case GI_INFO_TYPE_UNRESOLVED:
2166
+ rb_raise(rb_eNotImpError,
2167
+ "TODO: free GIArgument(GSList)[interface(%s)](%s) everything",
2168
+ g_info_type_to_string(type),
2169
+ g_type_name(gtype));
2170
+ break;
2171
+ default:
2172
+ g_assert_not_reached();
2173
+ break;
2174
+ }
2175
+ }
2176
+
2177
+ static void
2178
+ rb_gi_arguments_convert_return_value_free_everything_gslist(
2179
+ ReturnValueToRubyData *data)
2180
+ {
2181
+ if (!data->value->v_pointer)
2182
+ return;
2183
+
2184
+ GITypeTag element_type_tag = data->metadata->element_type.tag;
2185
+ switch (element_type_tag) {
2186
+ case GI_TYPE_TAG_VOID:
2187
+ case GI_TYPE_TAG_BOOLEAN:
2188
+ case GI_TYPE_TAG_INT8:
2189
+ case GI_TYPE_TAG_UINT8:
2190
+ case GI_TYPE_TAG_INT16:
2191
+ case GI_TYPE_TAG_UINT16:
2192
+ case GI_TYPE_TAG_INT32:
2193
+ case GI_TYPE_TAG_UINT32:
2194
+ case GI_TYPE_TAG_INT64:
2195
+ case GI_TYPE_TAG_UINT64:
2196
+ case GI_TYPE_TAG_FLOAT:
2197
+ case GI_TYPE_TAG_DOUBLE:
2198
+ case GI_TYPE_TAG_GTYPE:
2199
+ rb_raise(rb_eNotImpError,
2200
+ "TODO: free GIArgument(GSList)[%s] everything",
2201
+ g_type_tag_to_string(element_type_tag));
2202
+ break;
2203
+ case GI_TYPE_TAG_UTF8:
2204
+ case GI_TYPE_TAG_FILENAME:
2205
+ g_slist_free_full(data->value->v_pointer, g_free);
2206
+ break;
2207
+ case GI_TYPE_TAG_ARRAY:
2208
+ rb_raise(rb_eNotImpError,
2209
+ "TODO: free GIArgument(GSList)[%s] everything",
2210
+ g_type_tag_to_string(element_type_tag));
2211
+ break;
2212
+ case GI_TYPE_TAG_INTERFACE:
2213
+ rb_gi_arguments_convert_return_value_free_everything_gslist_interface(data);
2214
+ break;
2215
+ case GI_TYPE_TAG_GLIST:
2216
+ case GI_TYPE_TAG_GSLIST:
2217
+ case GI_TYPE_TAG_GHASH:
2218
+ case GI_TYPE_TAG_ERROR:
2219
+ case GI_TYPE_TAG_UNICHAR:
2220
+ rb_raise(rb_eNotImpError,
2221
+ "TODO: free GIArgument(GSList)[%s] everything",
2222
+ g_type_tag_to_string(element_type_tag));
2223
+ break;
2224
+ default:
2225
+ g_assert_not_reached();
2226
+ break;
2227
+ }
2228
+ }
2229
+
2230
+ static void
2231
+ rb_gi_arguments_convert_return_value_free_everything(ReturnValueToRubyData *data)
2232
+ {
2233
+ GITypeTag type_tag = data->metadata->type.tag;
2234
+ switch (type_tag) {
2235
+ case GI_TYPE_TAG_VOID:
2236
+ break;
2237
+ case GI_TYPE_TAG_BOOLEAN:
2238
+ case GI_TYPE_TAG_INT8:
2239
+ case GI_TYPE_TAG_UINT8:
2240
+ case GI_TYPE_TAG_INT16:
2241
+ case GI_TYPE_TAG_UINT16:
2242
+ case GI_TYPE_TAG_INT32:
2243
+ case GI_TYPE_TAG_UINT32:
2244
+ case GI_TYPE_TAG_INT64:
2245
+ case GI_TYPE_TAG_UINT64:
2246
+ case GI_TYPE_TAG_FLOAT:
2247
+ case GI_TYPE_TAG_DOUBLE:
2248
+ case GI_TYPE_TAG_GTYPE:
2249
+ rb_raise(rb_eNotImpError,
2250
+ "TODO: free GIArgument(%s) everything",
2251
+ g_type_tag_to_string(type_tag));
2252
+ break;
2253
+ case GI_TYPE_TAG_UTF8:
2254
+ g_free(data->value->v_string);
2255
+ break;
2256
+ case GI_TYPE_TAG_FILENAME:
2257
+ g_free(data->value->v_string);
2258
+ break;
2259
+ case GI_TYPE_TAG_ARRAY:
2260
+ rb_gi_arguments_convert_return_value_free_everything_array(data);
2261
+ break;
2262
+ case GI_TYPE_TAG_INTERFACE:
2263
+ rb_gi_arguments_convert_return_value_free_everything_interface(data);
2264
+ break;
2265
+ case GI_TYPE_TAG_GLIST:
2266
+ rb_gi_arguments_convert_return_value_free_everything_glist(data);
2267
+ break;
2268
+ case GI_TYPE_TAG_GSLIST:
2269
+ rb_gi_arguments_convert_return_value_free_everything_gslist(data);
2270
+ break;
2271
+ case GI_TYPE_TAG_GHASH:
2272
+ g_hash_table_unref(data->value->v_pointer);
2273
+ break;
2274
+ case GI_TYPE_TAG_ERROR:
2275
+ case GI_TYPE_TAG_UNICHAR:
2276
+ rb_raise(rb_eNotImpError,
2277
+ "TODO: free GIArgument(%s) everything",
2278
+ g_type_tag_to_string(type_tag));
2279
+ break;
2280
+ default:
2281
+ g_assert_not_reached();
2282
+ break;
2283
+ }
2284
+ }
2285
+
2286
+ static VALUE
2287
+ rb_gi_arguments_convert_return_value_ensure_body(VALUE user_data)
2288
+ {
2289
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
2290
+
2291
+ switch (g_callable_info_get_caller_owns(data->args->info)) {
2292
+ case GI_TRANSFER_NOTHING:
2293
+ break;
2294
+ case GI_TRANSFER_CONTAINER:
2295
+ rb_gi_arguments_convert_return_value_free_container(data);
2296
+ break;
2297
+ case GI_TRANSFER_EVERYTHING:
2298
+ rb_gi_arguments_convert_return_value_free_everything(data);
2299
+ break;
2300
+ default:
2301
+ g_assert_not_reached();
2302
+ break;
2303
+ }
2304
+
2305
+ return Qnil;
2306
+ }
2307
+
2308
+ static VALUE
2309
+ rb_gi_arguments_convert_return_value_ensure_ensure(VALUE user_data)
2310
+ {
2311
+ ReturnValueToRubyData *data = (ReturnValueToRubyData *)user_data;
2312
+ rb_gi_arg_metadata_clear(data->metadata);
2313
+ return Qnil;
2314
+ }
2315
+
2316
+ static VALUE
2317
+ rb_gi_arguments_convert_return_value_ensure(VALUE user_data)
2318
+ {
2319
+ return rb_ensure(rb_gi_arguments_convert_return_value_ensure_body,
2320
+ user_data,
2321
+ rb_gi_arguments_convert_return_value_ensure_ensure,
2322
+ user_data);
2323
+ }
2324
+
2325
+ VALUE
2326
+ rb_gi_arguments_convert_return_value(RBGIArguments *args,
2327
+ GIArgument *return_value)
2328
+ {
2329
+ if (g_callable_info_may_return_null(args->info) &&
2330
+ !return_value->v_pointer) {
2331
+ GITypeInfo return_value_info;
2332
+ g_callable_info_load_return_type(args->info, &return_value_info);
2333
+ GITypeTag return_value_tag = g_type_info_get_tag(&return_value_info);
2334
+ switch (return_value_tag) {
2335
+ case GI_TYPE_TAG_GLIST:
2336
+ case GI_TYPE_TAG_GSLIST:
2337
+ return rb_ary_new();
2338
+ default:
2339
+ return Qnil;
2340
+ }
2341
+ }
2342
+
2343
+ ReturnValueToRubyData data;
2344
+ data.args = args;
2345
+ data.value = return_value;
2346
+ RBGIArgMetadata metadata;
2347
+ GITypeInfo *return_value_info = g_callable_info_get_return_type(args->info);
2348
+ rb_gi_arg_metadata_init_type_info(&metadata, return_value_info);
2349
+ data.metadata = &metadata;
2350
+
2351
+ return rb_ensure(rb_gi_arguments_convert_return_value_body, (VALUE)&data,
2352
+ rb_gi_arguments_convert_return_value_ensure, (VALUE)&data);
2353
+ }
2354
+
500
2355
  void
501
2356
  rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
502
2357
  VALUE rb_error)