gir_ffi 0.9.5 → 0.10.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +9 -0
- data/lib/ffi-glib/byte_array.rb +1 -1
- data/lib/ffi-glib/bytes.rb +4 -4
- data/lib/ffi-glib/container_class_methods.rb +2 -0
- data/lib/ffi-glib/iconv.rb +2 -2
- data/lib/ffi-glib/variant.rb +10 -2
- data/lib/ffi-gobject.rb +6 -14
- data/lib/ffi-gobject/object.rb +7 -0
- data/lib/ffi-gobject/object_class.rb +1 -1
- data/lib/ffi-gobject/param_spec.rb +12 -0
- data/lib/ffi-gobject/value.rb +20 -11
- data/lib/gir_ffi-base/gobject.rb +35 -3
- data/lib/gir_ffi-base/gobject/lib.rb +2 -0
- data/lib/gir_ffi/allocation_helper.rb +11 -0
- data/lib/gir_ffi/arg_helper.rb +4 -0
- data/lib/gir_ffi/boxed_base.rb +28 -32
- data/lib/gir_ffi/builders/argument_builder.rb +31 -6
- data/lib/gir_ffi/builders/c_to_ruby_convertor.rb +36 -7
- data/lib/gir_ffi/builders/callback_argument_builder.rb +24 -10
- data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +1 -1
- data/lib/gir_ffi/builders/field_builder.rb +28 -10
- data/lib/gir_ffi/builders/full_c_to_ruby_convertor.rb +2 -3
- data/lib/gir_ffi/builders/initializer_return_value_builder.rb +5 -1
- data/lib/gir_ffi/builders/null_argument_builder.rb +0 -12
- data/lib/gir_ffi/builders/pointer_value_convertor.rb +38 -0
- data/lib/gir_ffi/builders/return_value_builder.rb +12 -10
- data/lib/gir_ffi/builders/ruby_to_c_convertor.rb +21 -2
- data/lib/gir_ffi/builders/struct_builder.rb +9 -2
- data/lib/gir_ffi/builders/{boxed_builder.rb → struct_like.rb} +2 -5
- data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +5 -2
- data/lib/gir_ffi/builders/union_builder.rb +5 -2
- data/lib/gir_ffi/enum_base.rb +4 -0
- data/lib/gir_ffi/error_argument_info.rb +0 -16
- data/lib/gir_ffi/ffi_ext/pointer.rb +11 -5
- data/lib/gir_ffi/flags_base.rb +4 -0
- data/lib/gir_ffi/in_out_pointer.rb +5 -30
- data/lib/gir_ffi/in_pointer.rb +5 -4
- data/lib/gir_ffi/info_ext/i_type_info.rb +3 -5
- data/lib/gir_ffi/object_base.rb +4 -0
- data/lib/gir_ffi/sized_array.rb +20 -0
- data/lib/gir_ffi/struct_base.rb +13 -2
- data/lib/gir_ffi/struct_like_base.rb +53 -0
- data/lib/gir_ffi/union_base.rb +7 -1
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/destroy_notify_test.rb +4 -1
- data/test/ffi-gobject/param_spec_test.rb +18 -0
- data/test/gir_ffi/arg_helper_test.rb +17 -0
- data/test/gir_ffi/boxed_base_test.rb +24 -0
- data/test/gir_ffi/builders/argument_builder_test.rb +156 -63
- data/test/gir_ffi/builders/callback_argument_builder_test.rb +10 -10
- data/test/gir_ffi/builders/callback_builder_test.rb +31 -8
- data/test/gir_ffi/builders/field_builder_test.rb +32 -30
- data/test/gir_ffi/builders/function_builder_test.rb +251 -45
- data/test/gir_ffi/builders/initializer_builder_test.rb +17 -1
- data/test/gir_ffi/builders/return_value_builder_test.rb +115 -68
- data/test/gir_ffi/builders/struct_builder_test.rb +6 -0
- data/test/gir_ffi/builders/unintrospectable_builder_test.rb +4 -1
- data/test/gir_ffi/builders/vfunc_builder_test.rb +10 -10
- data/test/gir_ffi/in_out_pointer_test.rb +12 -81
- data/test/gir_ffi/in_pointer_test.rb +0 -17
- data/test/gir_ffi/info_ext/i_type_info_test.rb +0 -10
- data/test/gir_ffi/sized_array_test.rb +62 -0
- data/test/gir_ffi/struct_base_test.rb +24 -0
- data/test/gir_ffi/union_base_test.rb +24 -0
- data/test/gir_ffi/version_test.rb +1 -1
- data/test/integration/generated_gimarshallingtests_test.rb +32 -12
- data/test/integration/generated_regress_test.rb +9 -12
- metadata +12 -8
- data/lib/ffi-gobject/base.rb +0 -27
- data/lib/gir_ffi/user_data_argument_info.rb +0 -24
- data/lib/gir_ffi/user_data_type_info.rb +0 -22
@@ -4,32 +4,57 @@ module GirFFI
|
|
4
4
|
# Builder that generates code to convert values from C to Ruby. Used by
|
5
5
|
# argument builders.
|
6
6
|
class CToRubyConvertor
|
7
|
-
def initialize(type_info,
|
7
|
+
def initialize(type_info, argument, length_arg, ownership_transfer: nil)
|
8
8
|
@type_info = type_info
|
9
|
-
@
|
9
|
+
@argument = argument
|
10
10
|
@length_arg = length_arg
|
11
|
+
@ownership_transfer = ownership_transfer
|
11
12
|
end
|
12
13
|
|
13
14
|
def conversion
|
14
15
|
case @type_info.flattened_tag
|
15
16
|
when :utf8, :filename
|
16
|
-
|
17
|
+
if @ownership_transfer == :everything
|
18
|
+
"#{@argument}.tap { |it| it.autorelease = true }.to_utf8"
|
19
|
+
else
|
20
|
+
"#{@argument}.to_utf8"
|
21
|
+
end
|
22
|
+
when :object
|
23
|
+
base = "#{@type_info.argument_class_name}.wrap(#{conversion_argument_list})"
|
24
|
+
@ownership_transfer == :nothing ? "#{base}.tap { |it| it && it.ref }" : base
|
17
25
|
else
|
18
|
-
"#{
|
26
|
+
"#{argument_class}.#{conversion_method}(#{conversion_argument_list})"
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
22
30
|
private
|
23
31
|
|
32
|
+
def conversion_method
|
33
|
+
case @type_info.flattened_tag
|
34
|
+
when :struct, :union
|
35
|
+
case @ownership_transfer
|
36
|
+
when :everything
|
37
|
+
'wrap_own'
|
38
|
+
when :nothing
|
39
|
+
'wrap_copy'
|
40
|
+
else
|
41
|
+
'wrap'
|
42
|
+
end
|
43
|
+
else
|
44
|
+
'wrap'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
24
48
|
def conversion_argument_list
|
25
49
|
conversion_arguments.join(', ')
|
26
50
|
end
|
27
51
|
|
28
52
|
def conversion_arguments
|
29
|
-
|
30
|
-
|
53
|
+
case @type_info.flattened_tag
|
54
|
+
when :c
|
55
|
+
[@type_info.element_type.inspect, array_size, @argument]
|
31
56
|
else
|
32
|
-
@type_info.extra_conversion_arguments.map(&:inspect).push(@
|
57
|
+
@type_info.extra_conversion_arguments.map(&:inspect).push(@argument)
|
33
58
|
end
|
34
59
|
end
|
35
60
|
|
@@ -40,6 +65,10 @@ module GirFFI
|
|
40
65
|
@type_info.array_fixed_size
|
41
66
|
end
|
42
67
|
end
|
68
|
+
|
69
|
+
def argument_class
|
70
|
+
@type_info.argument_class_name
|
71
|
+
end
|
43
72
|
end
|
44
73
|
end
|
45
74
|
end
|
@@ -3,6 +3,7 @@ require 'gir_ffi/builders/base_argument_builder'
|
|
3
3
|
require 'gir_ffi/builders/c_to_ruby_convertor'
|
4
4
|
require 'gir_ffi/builders/closure_convertor'
|
5
5
|
require 'gir_ffi/builders/null_convertor'
|
6
|
+
require 'gir_ffi/builders/pointer_value_convertor'
|
6
7
|
|
7
8
|
module GirFFI
|
8
9
|
module Builders
|
@@ -62,11 +63,11 @@ module GirFFI
|
|
62
63
|
def post_conversion
|
63
64
|
case direction
|
64
65
|
when :out, :inout
|
65
|
-
[
|
66
|
+
[value_to_pointer_conversion]
|
66
67
|
when :error
|
67
68
|
[
|
68
69
|
"rescue => #{result_name}",
|
69
|
-
|
70
|
+
value_to_pointer_conversion,
|
70
71
|
'end'
|
71
72
|
]
|
72
73
|
else
|
@@ -82,12 +83,25 @@ module GirFFI
|
|
82
83
|
|
83
84
|
def pre_convertor_argument
|
84
85
|
if direction == :inout
|
85
|
-
|
86
|
+
pointer_to_value_conversion
|
86
87
|
else
|
87
88
|
method_argument_name
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
92
|
+
def pointer_value_convertor
|
93
|
+
@pointer_value_convertor ||= PointerValueConvertor.new(type_spec)
|
94
|
+
end
|
95
|
+
|
96
|
+
def pointer_to_value_conversion
|
97
|
+
pointer_value_convertor.pointer_to_value(out_parameter_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
def value_to_pointer_conversion
|
101
|
+
pointer_value_convertor.value_to_pointer(out_parameter_name,
|
102
|
+
post_convertor.conversion)
|
103
|
+
end
|
104
|
+
|
91
105
|
def pre_convertor
|
92
106
|
@pre_convertor ||= if closure?
|
93
107
|
ClosureConvertor.new(pre_convertor_argument)
|
@@ -108,10 +122,6 @@ module GirFFI
|
|
108
122
|
"#{pre_converted_name} = #{pre_convertor.conversion}"
|
109
123
|
end
|
110
124
|
|
111
|
-
def outgoing_post_conversion
|
112
|
-
"#{out_parameter_name}.set_value #{post_convertor.conversion}"
|
113
|
-
end
|
114
|
-
|
115
125
|
def post_convertor
|
116
126
|
@post_convertor ||= if type_info.needs_ruby_to_c_conversion_for_callbacks?
|
117
127
|
RubyToCConvertor.new(type_info, post_convertor_argument)
|
@@ -129,16 +139,20 @@ module GirFFI
|
|
129
139
|
end
|
130
140
|
|
131
141
|
def out_parameter_preparation
|
132
|
-
type_spec = type_info.tag_or_class
|
133
142
|
value = if allocated_by_us?
|
134
|
-
|
143
|
+
ffi_type = TypeMap.type_specification_to_ffi_type type_spec[1]
|
144
|
+
"GirFFI::AllocationHelper.allocate(#{ffi_type.inspect})" \
|
135
145
|
".tap { |ptr| #{method_argument_name}.put_pointer 0, ptr }"
|
136
146
|
else
|
137
|
-
|
147
|
+
method_argument_name
|
138
148
|
end
|
139
149
|
"#{out_parameter_name} = #{value}"
|
140
150
|
end
|
141
151
|
|
152
|
+
def type_spec
|
153
|
+
type_info.tag_or_class
|
154
|
+
end
|
155
|
+
|
142
156
|
# Check if an out argument needs to be allocated by us, the callee. Since
|
143
157
|
# caller_allocates is false by default, we must also check that the type
|
144
158
|
# is a pointer. For example, an out parameter of type gint8* will always
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'gir_ffi/builders/argument_builder'
|
3
|
+
require 'gir_ffi/builders/base_argument_builder'
|
4
|
+
require 'gir_ffi/builders/null_argument_builder'
|
5
|
+
require 'gir_ffi/builders/pointer_value_convertor'
|
3
6
|
require 'gir_ffi/variable_name_generator'
|
4
7
|
require 'gir_ffi/field_argument_info'
|
5
8
|
|
@@ -23,8 +26,7 @@ module GirFFI
|
|
23
26
|
def pre_conversion
|
24
27
|
[
|
25
28
|
"#{field_ptr} = @struct.to_ptr + #{field_offset}",
|
26
|
-
"#{
|
27
|
-
"#{bare_value} = #{typed_ptr}.to_value"
|
29
|
+
"#{bare_value} = #{pointer_to_value_conversion}"
|
28
30
|
]
|
29
31
|
end
|
30
32
|
|
@@ -54,6 +56,10 @@ module GirFFI
|
|
54
56
|
|
55
57
|
private
|
56
58
|
|
59
|
+
def pointer_to_value_conversion
|
60
|
+
PointerValueConvertor.new(field_type_tag).pointer_to_value(field_ptr)
|
61
|
+
end
|
62
|
+
|
57
63
|
def field_offset
|
58
64
|
@field_info.offset
|
59
65
|
end
|
@@ -71,7 +77,7 @@ module GirFFI
|
|
71
77
|
end
|
72
78
|
|
73
79
|
def field_type_tag
|
74
|
-
@field_type_tag ||= @field_info.field_type.tag_or_class
|
80
|
+
@field_type_tag ||= @field_info.field_type.tag_or_class
|
75
81
|
end
|
76
82
|
|
77
83
|
def field_type
|
@@ -112,7 +118,7 @@ module GirFFI
|
|
112
118
|
end
|
113
119
|
|
114
120
|
def ownership_transfer
|
115
|
-
:
|
121
|
+
:nothing
|
116
122
|
end
|
117
123
|
|
118
124
|
def caller_allocates?
|
@@ -233,7 +239,9 @@ module GirFFI
|
|
233
239
|
end
|
234
240
|
|
235
241
|
def setup_getter
|
236
|
-
|
242
|
+
return if container_defines_getter_method?
|
243
|
+
return if hidden_struct_type?
|
244
|
+
container_class.class_eval getter_def
|
237
245
|
end
|
238
246
|
|
239
247
|
def container_defines_getter_method?
|
@@ -241,7 +249,9 @@ module GirFFI
|
|
241
249
|
end
|
242
250
|
|
243
251
|
def setup_setter
|
244
|
-
|
252
|
+
return unless info.writable?
|
253
|
+
return if hidden_struct_type?
|
254
|
+
container_class.class_eval setter_def
|
245
255
|
end
|
246
256
|
|
247
257
|
def getter_def
|
@@ -254,22 +264,25 @@ module GirFFI
|
|
254
264
|
builder = setter_builder
|
255
265
|
|
256
266
|
field_ptr = builder.new_variable
|
257
|
-
typed_ptr = builder.new_variable
|
258
267
|
|
259
268
|
<<-CODE.reset_indentation
|
260
269
|
def #{info.name}= #{builder.method_argument_name}
|
261
270
|
#{field_ptr} = @struct.to_ptr + #{info.offset}
|
262
|
-
#{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag}, #{field_ptr})
|
263
271
|
#{builder.pre_conversion.join("\n ")}
|
264
|
-
#{
|
272
|
+
#{value_storage(field_ptr, builder)}
|
265
273
|
end
|
266
274
|
CODE
|
267
275
|
end
|
268
276
|
|
269
277
|
private
|
270
278
|
|
279
|
+
def value_storage(typed_ptr, builder)
|
280
|
+
PointerValueConvertor.new(field_type_tag).
|
281
|
+
value_to_pointer(typed_ptr, builder.call_argument_name)
|
282
|
+
end
|
283
|
+
|
271
284
|
def field_type_tag
|
272
|
-
@field_type_tag ||=
|
285
|
+
@field_type_tag ||= field_type.tag_or_class
|
273
286
|
end
|
274
287
|
|
275
288
|
def container_class
|
@@ -296,6 +309,11 @@ module GirFFI
|
|
296
309
|
@setter_builder ||= ArgumentBuilder.new(VariableNameGenerator.new,
|
297
310
|
field_argument_info)
|
298
311
|
end
|
312
|
+
|
313
|
+
# rubocop:disable Style/ZeroLengthPredicate
|
314
|
+
def hidden_struct_type?
|
315
|
+
field_type.flattened_tag == :struct && field_type.interface.size == 0
|
316
|
+
end
|
299
317
|
end
|
300
318
|
end
|
301
319
|
end
|
@@ -7,11 +7,10 @@ module GirFFI
|
|
7
7
|
# GValue unpacking. Used by argument builders.
|
8
8
|
class FullCToRubyConvertor < CToRubyConvertor
|
9
9
|
def conversion
|
10
|
-
base = super
|
11
10
|
if @type_info.gvalue?
|
12
|
-
"#{
|
11
|
+
"GObject::Value.wrap(#{@argument}).get_value"
|
13
12
|
else
|
14
|
-
|
13
|
+
super
|
15
14
|
end
|
16
15
|
end
|
17
16
|
end
|
@@ -6,7 +6,11 @@ module GirFFI
|
|
6
6
|
# Implements post-conversion for initializer functions
|
7
7
|
class InitializerReturnValueBuilder < BaseReturnValueBuilder
|
8
8
|
def post_conversion
|
9
|
-
[
|
9
|
+
result = []
|
10
|
+
if specialized_type_tag == :struct
|
11
|
+
result << "#{capture_variable_name}.autorelease = true"
|
12
|
+
end
|
13
|
+
result << "store_pointer(#{capture_variable_name})"
|
10
14
|
end
|
11
15
|
end
|
12
16
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GirFFI
|
3
|
+
module Builders
|
4
|
+
# Encapsulates knowledge about how to store values in pointers, and how to
|
5
|
+
# fetch values from pointers.
|
6
|
+
class PointerValueConvertor
|
7
|
+
def initialize(type_spec)
|
8
|
+
@type_spec = type_spec
|
9
|
+
end
|
10
|
+
|
11
|
+
def pointer_to_value(ptr_exp)
|
12
|
+
case ffi_type_spec
|
13
|
+
when Module
|
14
|
+
"#{ffi_type_spec}.get_value_from_pointer(#{ptr_exp}, 0)"
|
15
|
+
when Symbol
|
16
|
+
"#{ptr_exp}.get_#{ffi_type_spec}(0)"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def value_to_pointer(ptr_exp, value_exp)
|
21
|
+
case ffi_type_spec
|
22
|
+
when Module
|
23
|
+
"#{ffi_type_spec}.copy_value_to_pointer(#{value_exp}, #{ptr_exp})"
|
24
|
+
when Symbol
|
25
|
+
"#{ptr_exp}.put_#{ffi_type_spec} 0, #{value_exp}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :type_spec
|
32
|
+
|
33
|
+
def ffi_type_spec
|
34
|
+
TypeMap.type_specification_to_ffi_type type_spec
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -8,11 +8,11 @@ module GirFFI
|
|
8
8
|
# Implements building post-processing statements for return values.
|
9
9
|
class ReturnValueBuilder < BaseReturnValueBuilder
|
10
10
|
def post_conversion
|
11
|
+
result = []
|
11
12
|
if has_post_conversion?
|
12
|
-
|
13
|
-
else
|
14
|
-
[]
|
13
|
+
result << "#{post_converted_name} = #{post_convertor.conversion}"
|
15
14
|
end
|
15
|
+
result
|
16
16
|
end
|
17
17
|
|
18
18
|
def has_post_conversion?
|
@@ -26,13 +26,15 @@ module GirFFI
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def post_convertor
|
29
|
-
@post_convertor ||=
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
@post_convertor ||=
|
30
|
+
if closure?
|
31
|
+
ClosureConvertor.new(capture_variable_name)
|
32
|
+
else
|
33
|
+
FullCToRubyConvertor.new(type_info,
|
34
|
+
capture_variable_name,
|
35
|
+
length_argument_name,
|
36
|
+
ownership_transfer: arginfo.ownership_transfer)
|
37
|
+
end
|
36
38
|
end
|
37
39
|
|
38
40
|
def length_argument_name
|
@@ -4,19 +4,38 @@ module GirFFI
|
|
4
4
|
# Builder that generates code to convert values from Ruby to C. Used by
|
5
5
|
# argument builders.
|
6
6
|
class RubyToCConvertor
|
7
|
-
def initialize(type_info, argument_name)
|
7
|
+
def initialize(type_info, argument_name, ownership_transfer: nil)
|
8
8
|
@type_info = type_info
|
9
9
|
@argument_name = argument_name
|
10
|
+
@ownership_transfer = ownership_transfer
|
10
11
|
end
|
11
12
|
|
12
13
|
def conversion
|
13
14
|
args = conversion_arguments @argument_name
|
14
|
-
"#{@type_info.argument_class_name}
|
15
|
+
"#{@type_info.argument_class_name}.#{conversion_method}(#{args})"
|
15
16
|
end
|
16
17
|
|
17
18
|
def conversion_arguments(name)
|
18
19
|
@type_info.extra_conversion_arguments.map(&:inspect).push(name).join(', ')
|
19
20
|
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def conversion_method
|
25
|
+
case @type_info.flattened_tag
|
26
|
+
when :utf8
|
27
|
+
'from_utf8'
|
28
|
+
when :struct, :c
|
29
|
+
case @ownership_transfer
|
30
|
+
when :everything
|
31
|
+
'copy_from'
|
32
|
+
else
|
33
|
+
'from'
|
34
|
+
end
|
35
|
+
else
|
36
|
+
'from'
|
37
|
+
end
|
38
|
+
end
|
20
39
|
end
|
21
40
|
end
|
22
41
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'gir_ffi/builders/
|
2
|
+
require 'gir_ffi/builders/registered_type_builder'
|
3
|
+
require 'gir_ffi/builders/struct_like'
|
3
4
|
require 'gir_ffi/struct_base'
|
4
5
|
|
5
6
|
module GirFFI
|
6
7
|
module Builders
|
7
8
|
# Implements the creation of a class representing a Struct.
|
8
|
-
class StructBuilder <
|
9
|
+
class StructBuilder < RegisteredTypeBuilder
|
10
|
+
include StructLike
|
11
|
+
|
9
12
|
def layout_superclass
|
10
13
|
FFI::Struct
|
11
14
|
end
|
@@ -21,6 +24,10 @@ module GirFFI
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
27
|
+
if GObject.type_fundamental(info.gtype) == GObject::TYPE_BOXED
|
28
|
+
return BoxedBase
|
29
|
+
end
|
30
|
+
|
24
31
|
StructBase
|
25
32
|
end
|
26
33
|
end
|