gir_ffi 0.4.2 → 0.4.3
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.
- data/History.txt +6 -0
- data/lib/ffi-glib/strv.rb +22 -0
- data/lib/ffi-glib.rb +1 -0
- data/lib/ffi-gobject_introspection/i_constant_info.rb +7 -0
- data/lib/ffi-gobject_introspection/lib.rb +1 -13
- data/lib/gir_ffi/builder/argument/base.rb +29 -9
- data/lib/gir_ffi/builder/argument/in_base.rb +2 -3
- data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
- data/lib/gir_ffi/builder/argument.rb +178 -143
- data/lib/gir_ffi/builder/field.rb +2 -2
- data/lib/gir_ffi/builder/function.rb +1 -1
- data/lib/gir_ffi/in_out_pointer.rb +19 -13
- data/lib/gir_ffi/in_pointer.rb +4 -0
- data/lib/gir_ffi/info_ext/i_registered_type_info.rb +14 -0
- data/lib/gir_ffi/info_ext/i_type_info.rb +55 -11
- data/lib/gir_ffi/version.rb +1 -1
- data/test/gir_ffi/builder/argument/base_test.rb +8 -12
- data/test/gir_ffi/builder/function_test.rb +5 -5
- data/test/gir_ffi/builder/type/struct_test.rb +1 -0
- data/test/gir_ffi/info_ext/i_type_info_test.rb +33 -13
- data/test/integration/generated_gimarshallingtests_test.rb +18 -14
- data/test/lib/Makefile.am +1 -1
- metadata +4 -2
data/History.txt
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module GLib
|
2
|
+
# Extra methods for GLib::Strv.
|
3
|
+
class Strv
|
4
|
+
def self.from it
|
5
|
+
case it
|
6
|
+
when nil
|
7
|
+
nil
|
8
|
+
when FFI::Pointer
|
9
|
+
wrap it
|
10
|
+
when self
|
11
|
+
it
|
12
|
+
else
|
13
|
+
from_enumerable it
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_enumerable enum
|
18
|
+
self.wrap GirFFI::InPointer.from_array :utf8, enum
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/ffi-glib.rb
CHANGED
@@ -2,7 +2,14 @@ module GObjectIntrospection
|
|
2
2
|
# Wraps a GIConstantInfo struct; represents an constant.
|
3
3
|
class IConstantInfo < IBaseInfo
|
4
4
|
TYPE_TAG_TO_UNION_MEMBER = {
|
5
|
+
:gint8 => :v_int8,
|
6
|
+
:gint16 => :v_int16,
|
5
7
|
:gint32 => :v_int32,
|
8
|
+
:gint64 => :v_int64,
|
9
|
+
:guint8 => :v_uint8,
|
10
|
+
:guint16 => :v_uint16,
|
11
|
+
:guint32 => :v_uint32,
|
12
|
+
:guint64 => :v_uint64,
|
6
13
|
:gdouble => :v_double,
|
7
14
|
:utf8 => :v_string
|
8
15
|
}
|
@@ -3,19 +3,7 @@ require 'ffi'
|
|
3
3
|
module GObjectIntrospection
|
4
4
|
module Lib
|
5
5
|
extend FFI::Library
|
6
|
-
|
7
|
-
ffi_lib "girepository-1.0.so.1"
|
8
|
-
rescue LoadError
|
9
|
-
begin
|
10
|
-
ffi_lib "girepository-1.0.so.0"
|
11
|
-
warn "This old version of gobject-introspection is not supported by GirFFI."
|
12
|
-
warn "Please upgrade to at least version 0.10.0."
|
13
|
-
rescue LoadError
|
14
|
-
ffi_lib "girepository-1.0"
|
15
|
-
warn "This platform and/or version of gobject-introspection are not supported by GirFFI."
|
16
|
-
warn "Please file bugs for any errors found."
|
17
|
-
end
|
18
|
-
end
|
6
|
+
ffi_lib "girepository-1.0"
|
19
7
|
|
20
8
|
# IRepository
|
21
9
|
enum :IRepositoryLoadFlags, [:LAZY, (1<<0)]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'gir_ffi/info_ext/i_registered_type_info'
|
2
|
+
|
1
3
|
module GirFFI
|
2
4
|
module Builder
|
3
5
|
module Argument
|
@@ -17,7 +19,7 @@ module GirFFI
|
|
17
19
|
|
18
20
|
attr_accessor :length_arg, :array_arg
|
19
21
|
|
20
|
-
def initialize var_gen, name, typeinfo
|
22
|
+
def initialize var_gen, name, typeinfo, direction
|
21
23
|
@typeinfo = typeinfo
|
22
24
|
@inarg = nil
|
23
25
|
@retname = nil
|
@@ -35,6 +37,14 @@ module GirFFI
|
|
35
37
|
type_info.tag
|
36
38
|
end
|
37
39
|
|
40
|
+
def specialized_type_tag
|
41
|
+
type_info.flattened_tag
|
42
|
+
end
|
43
|
+
|
44
|
+
def type_specification
|
45
|
+
type_info.type_specification
|
46
|
+
end
|
47
|
+
|
38
48
|
TAG_TO_WRAPPER_CLASS_MAP = {
|
39
49
|
:glist => 'GLib::List',
|
40
50
|
:gslist => 'GLib::SList',
|
@@ -47,14 +57,25 @@ module GirFFI
|
|
47
57
|
def argument_class_name
|
48
58
|
case (tag = type_tag)
|
49
59
|
when :interface
|
50
|
-
|
51
|
-
# FIXME: Extract to ITypeInfo.
|
52
|
-
"::#{iface.safe_namespace}::#{iface.name}"
|
60
|
+
type_info.interface_type_name
|
53
61
|
when :array
|
54
|
-
|
55
|
-
|
56
|
-
|
62
|
+
case type_info.array_type
|
63
|
+
when :byte_array
|
64
|
+
'GLib::ByteArray'
|
65
|
+
when :array
|
57
66
|
'GLib::Array'
|
67
|
+
when :ptr_array
|
68
|
+
'GLib::PtrArray'
|
69
|
+
else # :c
|
70
|
+
if type_info.zero_terminated?
|
71
|
+
if type_info.element_type == :utf8
|
72
|
+
'GLib::Strv'
|
73
|
+
else
|
74
|
+
'GirFFI::InPointer'
|
75
|
+
end
|
76
|
+
else
|
77
|
+
'GirFFI::InPointer'
|
78
|
+
end
|
58
79
|
end
|
59
80
|
else
|
60
81
|
TAG_TO_WRAPPER_CLASS_MAP[tag]
|
@@ -65,8 +86,7 @@ module GirFFI
|
|
65
86
|
type = type_info.param_type(index)
|
66
87
|
tag = type.tag
|
67
88
|
base = if tag == :interface
|
68
|
-
|
69
|
-
"::#{iface.safe_namespace}::#{iface.name}"
|
89
|
+
type.interface_type_name
|
70
90
|
else
|
71
91
|
tag.inspect
|
72
92
|
end
|
@@ -4,12 +4,11 @@ module GirFFI
|
|
4
4
|
# Abstract base class implementing argument processing for arguments
|
5
5
|
# with direction :in.
|
6
6
|
class InBase < Base
|
7
|
-
def initialize var_gen, name, typeinfo
|
8
|
-
super var_gen, name, typeinfo
|
7
|
+
def initialize var_gen, name, typeinfo, direction
|
8
|
+
super var_gen, name, typeinfo, direction
|
9
9
|
@inarg = @name
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
@@ -4,8 +4,8 @@ module GirFFI
|
|
4
4
|
# Abstract base class implementing argument processing for arguments
|
5
5
|
# with direction :inout.
|
6
6
|
class InOutBase < Base
|
7
|
-
def initialize var_gen, name, typeinfo
|
8
|
-
super var_gen, name, typeinfo
|
7
|
+
def initialize var_gen, name, typeinfo, direction
|
8
|
+
super var_gen, name, typeinfo, direction
|
9
9
|
@inarg = @name
|
10
10
|
end
|
11
11
|
|
@@ -16,6 +16,3 @@ module GirFFI
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
@@ -22,28 +22,22 @@ module GirFFI::Builder
|
|
22
22
|
module InArgument
|
23
23
|
def self.build var_gen, arginfo, libmodule
|
24
24
|
type = arginfo.argument_type
|
25
|
-
builder_for var_gen, arginfo.name, type, libmodule
|
25
|
+
builder_for var_gen, arginfo.name, type, arginfo.direction, libmodule
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.builder_for var_gen, name, type, libmodule
|
28
|
+
def self.builder_for var_gen, name, type, direction, libmodule
|
29
29
|
klass = case type.tag
|
30
30
|
when :interface
|
31
31
|
case type.interface.info_type
|
32
32
|
when :callback
|
33
33
|
return CallbackInArgument.new var_gen, name, type, libmodule
|
34
34
|
else
|
35
|
-
|
36
|
-
end
|
37
|
-
when :array
|
38
|
-
if type.array_type == :c
|
39
|
-
CArrayInArgument
|
40
|
-
else
|
41
|
-
RegularInArgument
|
35
|
+
RegularArgument
|
42
36
|
end
|
43
37
|
else
|
44
|
-
|
38
|
+
RegularArgument
|
45
39
|
end
|
46
|
-
return klass.new var_gen, name, type
|
40
|
+
return klass.new var_gen, name, type, direction
|
47
41
|
end
|
48
42
|
end
|
49
43
|
|
@@ -51,7 +45,7 @@ module GirFFI::Builder
|
|
51
45
|
# :in.
|
52
46
|
class CallbackInArgument < Argument::InBase
|
53
47
|
def initialize var_gen, name, type, libmodule
|
54
|
-
super var_gen, name, type
|
48
|
+
super var_gen, name, type, :in
|
55
49
|
@libmodule = libmodule
|
56
50
|
end
|
57
51
|
|
@@ -62,19 +56,6 @@ module GirFFI::Builder
|
|
62
56
|
end
|
63
57
|
end
|
64
58
|
|
65
|
-
# Implements argument processing for array arguments with direction :in.
|
66
|
-
class CArrayInArgument < Argument::InBase
|
67
|
-
def pre
|
68
|
-
pr = []
|
69
|
-
size = type_info.array_fixed_size
|
70
|
-
if size > -1
|
71
|
-
pr << "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
|
72
|
-
end
|
73
|
-
pr << "#{callarg} = GirFFI::InPointer.from_array #{elm_t}, #{@name}"
|
74
|
-
pr
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
59
|
# Implements argument processing for arguments with direction :in whose
|
79
60
|
# type-specific processing is left to FFI (e.g., ints and floats, and
|
80
61
|
# objects that implement to_ptr.).
|
@@ -87,38 +68,160 @@ module GirFFI::Builder
|
|
87
68
|
#
|
88
69
|
# Implements argument processing for void pointer arguments with
|
89
70
|
# direction :in.
|
90
|
-
|
71
|
+
#
|
72
|
+
# Implements argument processing for interface arguments with direction
|
73
|
+
# :inout (structs, objects, etc.).
|
74
|
+
#
|
75
|
+
# Implements argument processing for arguments with direction
|
76
|
+
# :out that are neither arrays nor 'interfaces'.
|
77
|
+
class RegularArgument < Argument::Base
|
78
|
+
def initialize var_gen, name, typeinfo, direction
|
79
|
+
super var_gen, name, typeinfo, direction
|
80
|
+
@direction = direction
|
81
|
+
end
|
82
|
+
|
83
|
+
def inarg
|
84
|
+
if has_input_value?
|
85
|
+
@array_arg.nil? ? @name : nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def retname
|
90
|
+
if has_output_value?
|
91
|
+
@retname ||= @var_gen.new_var
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
91
95
|
def pre
|
92
96
|
pr = []
|
93
|
-
|
94
|
-
|
97
|
+
if has_input_value?
|
98
|
+
pr << fixed_array_size_check if needs_size_check?
|
99
|
+
pr << array_length_assignment if is_array_length_parameter?
|
100
|
+
end
|
101
|
+
pr << set_function_call_argument
|
95
102
|
pr
|
96
103
|
end
|
97
104
|
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
|
105
|
+
def post
|
106
|
+
result = []
|
107
|
+
if has_output_value?
|
108
|
+
value = case @direction
|
109
|
+
when :inout
|
110
|
+
"#{argument_class_name}.wrap(#{output_conversion_arguments})"
|
111
|
+
when :out
|
112
|
+
"#{callarg}.to_value"
|
113
|
+
end
|
114
|
+
result << "#{retname} = #{value}"
|
115
|
+
end
|
116
|
+
result
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def is_array_length_parameter?
|
122
|
+
@array_arg
|
123
|
+
end
|
124
|
+
|
125
|
+
def needs_size_check?
|
126
|
+
if type_tag == :array
|
127
|
+
size = type_info.array_fixed_size
|
128
|
+
if size > -1
|
129
|
+
true
|
130
|
+
end
|
102
131
|
end
|
103
132
|
end
|
104
133
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
134
|
+
def fixed_array_size_check
|
135
|
+
size = type_info.array_fixed_size
|
136
|
+
"GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
|
137
|
+
end
|
138
|
+
|
139
|
+
def has_output_value?
|
140
|
+
@direction == :inout || @direction == :out
|
141
|
+
end
|
142
|
+
|
143
|
+
def has_input_value?
|
144
|
+
@direction == :inout || @direction == :in
|
145
|
+
end
|
146
|
+
|
147
|
+
def array_length_assignment
|
148
|
+
arrname = @array_arg.name
|
149
|
+
"#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length"
|
150
|
+
end
|
151
|
+
|
152
|
+
def set_function_call_argument
|
153
|
+
value = if @direction == :out
|
154
|
+
"GirFFI::InOutPointer.for #{type_tag.inspect}"
|
155
|
+
else
|
156
|
+
if needs_ingoing_parameter_conversion?
|
157
|
+
parameter_conversion
|
158
|
+
else
|
159
|
+
@name
|
160
|
+
end
|
161
|
+
end
|
162
|
+
"#{callarg} = #{value}"
|
163
|
+
end
|
164
|
+
|
165
|
+
def needs_outgoing_parameter_conversion?
|
166
|
+
case specialized_type_tag
|
167
|
+
when :object, :struct, :utf8, :void, :glist, :gslist, :ghash, :array, :c, :strv
|
168
|
+
true
|
169
|
+
else
|
170
|
+
false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def needs_ingoing_parameter_conversion?
|
175
|
+
case specialized_type_tag
|
176
|
+
when :object, :struct, :utf8, :void, :glist, :gslist, :ghash, :array, :c, :strv
|
177
|
+
true
|
178
|
+
else
|
179
|
+
false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def parameter_conversion
|
184
|
+
base = "#{argument_class_name}.from(#{parameter_conversion_arguments})"
|
185
|
+
if has_output_value?
|
186
|
+
"GirFFI::InOutPointer.from :pointer, #{base}"
|
112
187
|
else
|
113
|
-
|
188
|
+
base
|
114
189
|
end
|
115
190
|
end
|
191
|
+
|
192
|
+
def output_conversion_arguments
|
193
|
+
conversion_arguments "#{callarg}.to_value"
|
194
|
+
end
|
195
|
+
|
196
|
+
def parameter_conversion_arguments
|
197
|
+
conversion_arguments @name
|
198
|
+
end
|
199
|
+
|
200
|
+
def conversion_arguments name
|
201
|
+
case specialized_type_tag
|
202
|
+
when :utf8, :void
|
203
|
+
"#{self_t}, #{name}"
|
204
|
+
when :glist, :gslist, :ghash, :array
|
205
|
+
"#{elm_t}, #{name}"
|
206
|
+
when :c
|
207
|
+
"#{type_specification}, #{name}"
|
208
|
+
when :strv
|
209
|
+
"#{name}"
|
210
|
+
else
|
211
|
+
"#{name}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def self_t
|
216
|
+
type_tag.inspect
|
217
|
+
end
|
116
218
|
end
|
117
219
|
|
118
220
|
# Implements argument processing for arguments with direction :out.
|
119
221
|
module OutArgument
|
120
222
|
def self.build var_gen, arginfo, libmodule
|
121
223
|
type = arginfo.argument_type
|
224
|
+
direction = arginfo.direction
|
122
225
|
klass = case type.tag
|
123
226
|
when :interface
|
124
227
|
case type.interface.info_type
|
@@ -139,35 +242,19 @@ module GirFFI::Builder
|
|
139
242
|
when :c
|
140
243
|
CArrayOutArgument
|
141
244
|
when :array
|
142
|
-
it = PointerLikeOutArgument.new var_gen, arginfo.name, type
|
245
|
+
it = PointerLikeOutArgument.new var_gen, arginfo.name, type, direction
|
143
246
|
it.extend WithTypedContainerPostMethod
|
144
247
|
return it
|
145
248
|
end
|
146
249
|
end
|
147
|
-
when :glist, :gslist
|
148
|
-
it = PointerLikeOutArgument.new var_gen, arginfo.name, type
|
149
|
-
it.extend WithTypedContainerPostMethod
|
150
|
-
return it
|
151
|
-
when :ghash
|
152
|
-
it = PointerLikeOutArgument.new var_gen, arginfo.name, type
|
250
|
+
when :glist, :gslist, :ghash
|
251
|
+
it = PointerLikeOutArgument.new var_gen, arginfo.name, type, direction
|
153
252
|
it.extend WithTypedContainerPostMethod
|
154
253
|
return it
|
155
254
|
else
|
156
|
-
|
255
|
+
RegularArgument
|
157
256
|
end
|
158
|
-
klass.new var_gen, arginfo.name, type
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# Implements argument processing for arguments with direction
|
163
|
-
# :out that are neither arrays nor 'interfaces'.
|
164
|
-
class RegularOutArgument < Argument::OutBase
|
165
|
-
def pre
|
166
|
-
[ "#{callarg} = GirFFI::InOutPointer.for #{type_tag.inspect}" ]
|
167
|
-
end
|
168
|
-
|
169
|
-
def post
|
170
|
-
[ "#{retname} = #{callarg}.to_value" ]
|
257
|
+
klass.new var_gen, arginfo.name, type, direction
|
171
258
|
end
|
172
259
|
end
|
173
260
|
|
@@ -237,13 +324,14 @@ module GirFFI::Builder
|
|
237
324
|
module InOutArgument
|
238
325
|
def self.build var_gen, arginfo, libmodule
|
239
326
|
type = arginfo.argument_type
|
327
|
+
direction = arginfo.direction
|
240
328
|
klass = case type.tag
|
241
329
|
when :interface
|
242
330
|
case type.interface.info_type
|
243
331
|
when :enum, :flags
|
244
332
|
EnumInOutArgument
|
245
333
|
else
|
246
|
-
|
334
|
+
RegularArgument
|
247
335
|
end
|
248
336
|
when :array
|
249
337
|
if type.zero_terminated?
|
@@ -253,27 +341,16 @@ module GirFFI::Builder
|
|
253
341
|
when :c
|
254
342
|
CArrayInOutArgument
|
255
343
|
when :array
|
256
|
-
|
257
|
-
it.extend WithTypedContainerInOutPreMethod
|
258
|
-
it.extend WithTypedContainerPostMethod
|
259
|
-
return it
|
344
|
+
RegularArgument
|
260
345
|
end
|
261
346
|
end
|
262
|
-
when :glist, :gslist
|
263
|
-
|
264
|
-
it.extend WithTypedContainerInOutPreMethod
|
265
|
-
it.extend WithTypedContainerPostMethod
|
266
|
-
return it
|
267
|
-
when :ghash
|
268
|
-
it = Argument::InOutBase.new var_gen, arginfo.name, type
|
269
|
-
it.extend WithTypedContainerInOutPreMethod
|
270
|
-
it.extend WithTypedContainerPostMethod
|
271
|
-
return it
|
347
|
+
when :glist, :gslist, :ghash
|
348
|
+
RegularArgument
|
272
349
|
else
|
273
350
|
RegularInOutArgument
|
274
351
|
end
|
275
352
|
|
276
|
-
klass.new var_gen, arginfo.name, type
|
353
|
+
klass.new var_gen, arginfo.name, type, direction
|
277
354
|
end
|
278
355
|
end
|
279
356
|
|
@@ -291,23 +368,11 @@ module GirFFI::Builder
|
|
291
368
|
end
|
292
369
|
end
|
293
370
|
|
294
|
-
# Implements argument processing for interface arguments with direction
|
295
|
-
# :inout (structs, objects, etc.).
|
296
|
-
class InterfaceInOutArgument < Argument::InOutBase
|
297
|
-
def pre
|
298
|
-
[ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{argument_class_name}.from(#{@name}).to_ptr" ]
|
299
|
-
end
|
300
|
-
|
301
|
-
def post
|
302
|
-
[ "#{retname} = #{argument_class_name}.wrap(#{callarg}.to_value)" ]
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
371
|
# Implements argument processing for strv arguments with direction
|
307
372
|
# :inout.
|
308
373
|
class StrvInOutArgument < Argument::InOutBase
|
309
374
|
def pre
|
310
|
-
[ "#{callarg} = GirFFI::InOutPointer.
|
375
|
+
[ "#{callarg} = GirFFI::InOutPointer.from #{type_specification}, #{@name}" ]
|
311
376
|
end
|
312
377
|
|
313
378
|
def post
|
@@ -329,12 +394,6 @@ module GirFFI::Builder
|
|
329
394
|
end
|
330
395
|
end
|
331
396
|
|
332
|
-
module WithTypedContainerInOutPreMethod
|
333
|
-
def pre
|
334
|
-
[ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{argument_class_name}.from(#{elm_t}, #{@name})" ]
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
397
|
# Implements argument processing for arguments with direction
|
339
398
|
# :inout that are neither arrays nor 'interfaces'.
|
340
399
|
class RegularInOutArgument < Argument::InOutBase
|
@@ -357,24 +416,25 @@ module GirFFI::Builder
|
|
357
416
|
builder_for(var_gen,
|
358
417
|
arginfo.name,
|
359
418
|
arginfo.return_type,
|
419
|
+
:return,
|
360
420
|
arginfo.constructor?)
|
361
421
|
end
|
362
422
|
|
363
|
-
def self.builder_for var_gen, name, type, is_constructor
|
423
|
+
def self.builder_for var_gen, name, type, direction, is_constructor
|
364
424
|
if type.tag == :interface and
|
365
425
|
[:interface, :object].include? type.interface.info_type
|
366
426
|
klass = if is_constructor
|
367
427
|
ConstructorReturnValue
|
368
428
|
else
|
369
|
-
|
429
|
+
WrappingReturnValue
|
370
430
|
end
|
371
|
-
klass.new var_gen, name, type
|
431
|
+
klass.new var_gen, name, type, direction
|
372
432
|
else
|
373
|
-
builder_for_field_getter var_gen, name, type
|
433
|
+
builder_for_field_getter var_gen, name, type, direction
|
374
434
|
end
|
375
435
|
end
|
376
436
|
|
377
|
-
def self.builder_for_field_getter var_gen, name, type
|
437
|
+
def self.builder_for_field_getter var_gen, name, type, direction
|
378
438
|
klass = case type.tag
|
379
439
|
when :void
|
380
440
|
if type.pointer?
|
@@ -385,33 +445,27 @@ module GirFFI::Builder
|
|
385
445
|
when :interface
|
386
446
|
case type.interface.info_type
|
387
447
|
when :struct, :union, :interface, :object
|
388
|
-
|
448
|
+
WrappingReturnValue
|
389
449
|
else
|
390
450
|
RegularReturnValue
|
391
451
|
end
|
392
452
|
when :array
|
393
453
|
if type.zero_terminated?
|
394
|
-
|
454
|
+
WrappingReturnValue
|
395
455
|
else
|
396
456
|
case type.array_type
|
397
457
|
when :c
|
398
458
|
CArrayReturnValue
|
399
459
|
when :array
|
400
|
-
it = ReturnValue.new var_gen, name, type
|
460
|
+
it = ReturnValue.new var_gen, name, type, direction
|
401
461
|
it.extend WithTypedContainerPostMethod
|
402
462
|
return it
|
403
|
-
when :byte_array
|
404
|
-
ByteArrayReturnValue
|
405
463
|
else
|
406
|
-
|
464
|
+
WrappingReturnValue
|
407
465
|
end
|
408
466
|
end
|
409
|
-
when :glist, :gslist
|
410
|
-
it = ReturnValue.new var_gen, name, type
|
411
|
-
it.extend WithTypedContainerPostMethod
|
412
|
-
return it
|
413
|
-
when :ghash
|
414
|
-
it = ReturnValue.new var_gen, name, type
|
467
|
+
when :glist, :gslist, :ghash
|
468
|
+
it = ReturnValue.new var_gen, name, type, direction
|
415
469
|
it.extend WithTypedContainerPostMethod
|
416
470
|
return it
|
417
471
|
when :utf8
|
@@ -419,7 +473,7 @@ module GirFFI::Builder
|
|
419
473
|
else
|
420
474
|
RegularReturnValue
|
421
475
|
end
|
422
|
-
klass.new var_gen, name, type
|
476
|
+
klass.new var_gen, name, type, direction
|
423
477
|
end
|
424
478
|
end
|
425
479
|
|
@@ -447,14 +501,16 @@ module GirFFI::Builder
|
|
447
501
|
# Implements argument processing for interface return values (interfaces
|
448
502
|
# and structs, but not objects, which need special handling for
|
449
503
|
# polymorphism and constructors).
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
# Implements argument processing for
|
457
|
-
|
504
|
+
#
|
505
|
+
# Implements argument processing for object return values when the method is
|
506
|
+
# not a constructor.
|
507
|
+
#
|
508
|
+
# Implements argument processing for NULL-terminated string array return values.
|
509
|
+
#
|
510
|
+
# Implements argument processing for GByteArray return values.
|
511
|
+
#
|
512
|
+
# Implements argument processing for GPtrArray return values.
|
513
|
+
class WrappingReturnValue < ReturnValue
|
458
514
|
def post
|
459
515
|
[ "#{retname} = #{argument_class_name}.wrap(#{cvar})" ]
|
460
516
|
end
|
@@ -476,13 +532,6 @@ module GirFFI::Builder
|
|
476
532
|
end
|
477
533
|
end
|
478
534
|
|
479
|
-
# Implements argument processing for NULL-terminated string array return values.
|
480
|
-
class StrvReturnValue < ReturnValue
|
481
|
-
def post
|
482
|
-
[ "#{retname} = GLib::Strv.wrap(#{cvar})" ]
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
535
|
# Implements argument processing for UTF8 string return values.
|
487
536
|
class Utf8ReturnValue < ReturnValue
|
488
537
|
def post
|
@@ -490,20 +539,6 @@ module GirFFI::Builder
|
|
490
539
|
end
|
491
540
|
end
|
492
541
|
|
493
|
-
# Implements argument processing for GByteArray return values.
|
494
|
-
class ByteArrayReturnValue < ReturnValue
|
495
|
-
def post
|
496
|
-
[ "#{retname} = GLib::ByteArray.wrap(#{cvar})" ]
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
# Implements argument processing for GPtrArray return values.
|
501
|
-
class PtrArrayReturnValue < ReturnValue
|
502
|
-
def post
|
503
|
-
[ "#{retname} = GLib::PtrArray.wrap(#{cvar})" ]
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
542
|
# Implements argument processing for other return values.
|
508
543
|
class RegularReturnValue < ReturnValue
|
509
544
|
def retval
|
@@ -45,13 +45,13 @@ module GirFFI
|
|
45
45
|
|
46
46
|
def return_value_builder
|
47
47
|
@rv_builder ||= ReturnValueFactory.builder_for_field_getter(
|
48
|
-
VariableNameGenerator.new, @info.name, @info.field_type)
|
48
|
+
VariableNameGenerator.new, @info.name, @info.field_type, :return)
|
49
49
|
end
|
50
50
|
|
51
51
|
def setter_builder
|
52
52
|
type = @info.field_type
|
53
53
|
vargen = VariableNameGenerator.new
|
54
|
-
Builder::InArgument.builder_for vargen, "value", type, @libmodule
|
54
|
+
Builder::InArgument.builder_for vargen, "value", type, :in, @libmodule
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -26,19 +26,6 @@ module GirFFI
|
|
26
26
|
ArgHelper.ptr_to_typed_array @sub_type, block, size
|
27
27
|
end
|
28
28
|
|
29
|
-
private
|
30
|
-
|
31
|
-
def adjust_value_out value
|
32
|
-
case @value_type
|
33
|
-
when :gboolean
|
34
|
-
(value != 0)
|
35
|
-
when :utf8
|
36
|
-
ArgHelper.ptr_to_utf8 value
|
37
|
-
else
|
38
|
-
value
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
29
|
def self.for type, sub_type=nil
|
43
30
|
ffi_type = TypeMap.map_basic_type_or_string type
|
44
31
|
ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
|
@@ -47,6 +34,11 @@ module GirFFI
|
|
47
34
|
end
|
48
35
|
|
49
36
|
def self.from type, value, sub_type=nil
|
37
|
+
if Array === type
|
38
|
+
arr_t, sub_t = *type
|
39
|
+
# TODO: Take array type into account (zero-terminated or not)
|
40
|
+
return self.from_array sub_t, value
|
41
|
+
end
|
50
42
|
value = adjust_value_in type, value
|
51
43
|
ffi_type = TypeMap.map_basic_type_or_string type
|
52
44
|
ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
|
@@ -85,6 +77,20 @@ module GirFFI
|
|
85
77
|
end
|
86
78
|
end
|
87
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def adjust_value_out value
|
84
|
+
case @value_type
|
85
|
+
when :gboolean
|
86
|
+
(value != 0)
|
87
|
+
when :utf8
|
88
|
+
ArgHelper.ptr_to_utf8 value
|
89
|
+
else
|
90
|
+
value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
88
94
|
end
|
89
95
|
end
|
90
96
|
|
data/lib/gir_ffi/in_pointer.rb
CHANGED
@@ -18,6 +18,10 @@ module GirFFI
|
|
18
18
|
def self.from type, val
|
19
19
|
return nil if val.nil?
|
20
20
|
case type
|
21
|
+
when Array
|
22
|
+
arr_t, sub_t = *type
|
23
|
+
# TODO: Take array type into account (zero-terminated or not)
|
24
|
+
self.from_array sub_t, val
|
21
25
|
when :utf8, :filename
|
22
26
|
from_utf8 val
|
23
27
|
when :gint32, :gint8
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'gir_ffi/builder_helper'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
module InfoExt
|
5
|
+
module IRegisteredTypeInfo
|
6
|
+
def full_type_name
|
7
|
+
"::#{safe_namespace}::#{name}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
GObjectIntrospection::IRegisteredTypeInfo.send :include, GirFFI::InfoExt::IRegisteredTypeInfo
|
14
|
+
|
@@ -24,6 +24,61 @@ module GirFFI
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def element_type
|
28
|
+
case tag
|
29
|
+
when :glist, :gslist, :array
|
30
|
+
subtype_tag 0
|
31
|
+
when :ghash
|
32
|
+
[subtype_tag(0), subtype_tag(1)]
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def interface_type_name
|
39
|
+
interface.full_type_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def type_specification
|
43
|
+
tag = self.tag
|
44
|
+
if tag == :array
|
45
|
+
"[#{flattened_array_type.inspect}, #{element_type.inspect}]"
|
46
|
+
else
|
47
|
+
tag.inspect
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def flattened_tag
|
52
|
+
case tag
|
53
|
+
when :interface
|
54
|
+
interface_type
|
55
|
+
when :array
|
56
|
+
flattened_array_type
|
57
|
+
else
|
58
|
+
tag
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def interface_type
|
63
|
+
interface.info_type
|
64
|
+
end
|
65
|
+
|
66
|
+
def flattened_array_type
|
67
|
+
if zero_terminated?
|
68
|
+
if element_type == :utf8
|
69
|
+
:strv
|
70
|
+
else
|
71
|
+
# TODO: Check that array_type == :c
|
72
|
+
# TODO: Perhaps distinguish :c from zero-terminated :c
|
73
|
+
:c
|
74
|
+
end
|
75
|
+
else
|
76
|
+
array_type
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
27
82
|
def subtype_tag index
|
28
83
|
st = param_type(index)
|
29
84
|
tag = st.tag
|
@@ -38,17 +93,6 @@ module GirFFI
|
|
38
93
|
return tag
|
39
94
|
end
|
40
95
|
end
|
41
|
-
|
42
|
-
def element_type
|
43
|
-
case tag
|
44
|
-
when :glist, :gslist, :array
|
45
|
-
subtype_tag 0
|
46
|
-
when :ghash
|
47
|
-
[subtype_tag(0), subtype_tag(1)]
|
48
|
-
else
|
49
|
-
nil
|
50
|
-
end
|
51
|
-
end
|
52
96
|
end
|
53
97
|
end
|
54
98
|
end
|
data/lib/gir_ffi/version.rb
CHANGED
@@ -9,7 +9,7 @@ describe GirFFI::Builder::Argument::Base do
|
|
9
9
|
|
10
10
|
mock(info = Object.new).param_type(0) { subtype }
|
11
11
|
|
12
|
-
builder = GirFFI::Builder::Argument::Base.new nil, 'foo', info
|
12
|
+
builder = GirFFI::Builder::Argument::Base.new nil, 'foo', info, :direction
|
13
13
|
assert_equal ":void", builder.subtype_tag_or_class_name
|
14
14
|
end
|
15
15
|
end
|
@@ -21,24 +21,21 @@ describe GirFFI::Builder::Argument::Base do
|
|
21
21
|
|
22
22
|
mock(info = Object.new).param_type(0) { subtype }
|
23
23
|
|
24
|
-
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
|
24
|
+
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
|
25
25
|
assert_equal ":foo", builder.subtype_tag_or_class_name
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe "for an array of interface class
|
30
|
-
it "returns the
|
31
|
-
mock(interface = Object.new).safe_namespace { "Foo" }
|
32
|
-
mock(interface).name { "Bar" }
|
33
|
-
|
29
|
+
describe "for an array of an interface class" do
|
30
|
+
it "returns the interface's full class name" do
|
34
31
|
mock(subtype = Object.new).tag { :interface }
|
35
|
-
mock(subtype).
|
32
|
+
mock(subtype).interface_type_name { "-full-type-name-" }
|
36
33
|
mock(subtype).pointer? { false }
|
37
34
|
|
38
35
|
mock(info = Object.new).param_type(0) { subtype }
|
39
36
|
|
40
|
-
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
|
41
|
-
assert_equal "
|
37
|
+
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
|
38
|
+
assert_equal "-full-type-name-", builder.subtype_tag_or_class_name
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
@@ -49,11 +46,10 @@ describe GirFFI::Builder::Argument::Base do
|
|
49
46
|
|
50
47
|
mock(info = Object.new).param_type(0) { subtype }
|
51
48
|
|
52
|
-
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
|
49
|
+
builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
|
53
50
|
assert_equal "[:pointer, :foo]", builder.subtype_tag_or_class_name
|
54
51
|
end
|
55
52
|
end
|
56
|
-
|
57
53
|
end
|
58
54
|
end
|
59
55
|
|
@@ -38,7 +38,7 @@ describe GirFFI::Builder::Function do
|
|
38
38
|
def self.test_array_gint16_in ints
|
39
39
|
n_ints = ints.nil? ? 0 : ints.length
|
40
40
|
_v1 = n_ints
|
41
|
-
_v2 = GirFFI::InPointer.
|
41
|
+
_v2 = GirFFI::InPointer.from([:c, :gint16], ints)
|
42
42
|
_v3 = DummyLib.regress_test_array_gint16_in _v1, _v2
|
43
43
|
return _v3
|
44
44
|
end
|
@@ -56,7 +56,7 @@ describe GirFFI::Builder::Function do
|
|
56
56
|
def self.test_callback_destroy_notify callback, user_data, notify
|
57
57
|
_v1 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"Regress\", \"TestCallbackUserData\", callback
|
58
58
|
DummyLib::CALLBACKS << _v1
|
59
|
-
_v2 = GirFFI::InPointer.from
|
59
|
+
_v2 = GirFFI::InPointer.from(:void, user_data)
|
60
60
|
_v3 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"GLib\", \"DestroyNotify\", notify
|
61
61
|
DummyLib::CALLBACKS << _v3
|
62
62
|
_v4 = DummyLib.regress_test_callback_destroy_notify _v1, _v2, _v3
|
@@ -74,7 +74,7 @@ describe GirFFI::Builder::Function do
|
|
74
74
|
|
75
75
|
expected = <<-CODE
|
76
76
|
def self.new_from_file x
|
77
|
-
_v1 = GirFFI::InPointer.from
|
77
|
+
_v1 = GirFFI::InPointer.from(:utf8, x)
|
78
78
|
_v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil
|
79
79
|
_v3 = DummyLib.regress_test_obj_new_from_file _v1, _v2
|
80
80
|
GirFFI::ArgHelper.check_error(_v2)
|
@@ -93,7 +93,7 @@ describe GirFFI::Builder::Function do
|
|
93
93
|
|
94
94
|
expected = <<-CODE
|
95
95
|
def self.gvalue_in value
|
96
|
-
_v1 = ::GObject::Value.from
|
96
|
+
_v1 = ::GObject::Value.from(value)
|
97
97
|
DummyLib.gi_marshalling_tests_gvalue_in _v1
|
98
98
|
|
99
99
|
end
|
@@ -109,7 +109,7 @@ describe GirFFI::Builder::Function do
|
|
109
109
|
|
110
110
|
expected = <<-CODE
|
111
111
|
def self.test_array_int_null_in arr
|
112
|
-
_v1 = GirFFI::InPointer.
|
112
|
+
_v1 = GirFFI::InPointer.from([:c, :gint32], arr)
|
113
113
|
len = arr.nil? ? 0 : arr.length
|
114
114
|
_v2 = len
|
115
115
|
DummyLib.regress_test_array_int_null_in _v1, _v2
|
@@ -21,19 +21,6 @@ describe GirFFI::InfoExt::ITypeInfo do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
describe "#subtype_tag" do
|
25
|
-
it "returns :gpointer if the param_type is a pointer with tag :void" do
|
26
|
-
type_info = testclass.new
|
27
|
-
|
28
|
-
stub(subtype0 = Object.new).tag { :void }
|
29
|
-
stub(subtype0).pointer? { true }
|
30
|
-
|
31
|
-
mock(type_info).param_type(0) { subtype0 }
|
32
|
-
|
33
|
-
assert_equal :gpointer, type_info.subtype_tag(0)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
24
|
describe "#element_type" do
|
38
25
|
it "returns the element type for lists" do
|
39
26
|
type_info = testclass.new
|
@@ -67,5 +54,38 @@ describe GirFFI::InfoExt::ITypeInfo do
|
|
67
54
|
result = type_info.element_type
|
68
55
|
result.must_be_nil
|
69
56
|
end
|
57
|
+
|
58
|
+
it "returns :gpointer if the element type is a pointer with tag :void" do
|
59
|
+
type_info = testclass.new
|
60
|
+
|
61
|
+
stub(elm_type = Object.new).tag { :void }
|
62
|
+
stub(elm_type).pointer? { true }
|
63
|
+
|
64
|
+
mock(type_info).tag {:glist}
|
65
|
+
mock(type_info).param_type(0) { elm_type }
|
66
|
+
|
67
|
+
assert_equal :gpointer, type_info.element_type
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#type_specification" do
|
72
|
+
describe "for a simple type" do
|
73
|
+
it "returns the type tag" do
|
74
|
+
type_info = testclass.new
|
75
|
+
mock(type_info).tag { :uint32 }
|
76
|
+
type_info.type_specification.must_equal ":uint32"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "for a zero-terminated array" do
|
81
|
+
it "returns the pair [:strv, element_type]" do
|
82
|
+
type_info = testclass.new
|
83
|
+
mock(type_info).tag { :array }
|
84
|
+
stub(type_info).element_type { :utf8 }
|
85
|
+
stub(type_info).zero_terminated? { true }
|
86
|
+
stub(type_info).array_type { :c }
|
87
|
+
type_info.type_specification.must_equal "[:strv, :utf8]"
|
88
|
+
end
|
89
|
+
end
|
70
90
|
end
|
71
91
|
end
|
@@ -490,20 +490,24 @@ describe "GIMarshallingTests" do
|
|
490
490
|
assert_equal [-1, 0, 1, 2], res
|
491
491
|
end
|
492
492
|
|
493
|
-
it "has a working function #array_gvariant_(none)_in"
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
#
|
505
|
-
|
506
|
-
|
493
|
+
it "has a working function #array_gvariant_(none)_in"
|
494
|
+
# FIXME: Test was disabled since the implementation of the return value
|
495
|
+
# handling was never correct.
|
496
|
+
#
|
497
|
+
#do
|
498
|
+
#v1 = GLib::Variant.new_int32(27)
|
499
|
+
#v2 = GLib::Variant.new_string("Hello")
|
500
|
+
#if GIMarshallingTests._builder.setup_method :array_gvariant_in
|
501
|
+
#GIMarshallingTests.array_gvariant_in [v1, v2]
|
502
|
+
#else
|
503
|
+
#GIMarshallingTests.array_gvariant_none_in [v1, v2]
|
504
|
+
#end
|
505
|
+
|
506
|
+
#pass
|
507
|
+
## TODO: Can we determine that result should be an array?
|
508
|
+
## assert_equal 27, res[0].get_int32
|
509
|
+
## assert_equal "Hello", res[1].get_string
|
510
|
+
#end
|
507
511
|
|
508
512
|
it "has a working function #array_in" do
|
509
513
|
GIMarshallingTests.array_in [-1, 0, 1, 2]
|
data/test/lib/Makefile.am
CHANGED
@@ -19,7 +19,7 @@ libgimarshallingtests_la_LDFLAGS = -module -avoid-version
|
|
19
19
|
# g-i doesn't ship these as shared libraries anymore; we build them here
|
20
20
|
Regress-1.0.gir: libregress.la Makefile
|
21
21
|
$(AM_V_GEN) g-ir-scanner --include=cairo-1.0 --include=Gio-2.0 \
|
22
|
-
--namespace=Regress --nsversion=1.0 \
|
22
|
+
--namespace=Regress --nsversion=1.0 --pkg=cairo-gobject \
|
23
23
|
--warn-all --warn-error \
|
24
24
|
--library=libregress.la \
|
25
25
|
--libtool="$(top_builddir)/libtool" \
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gir_ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- lib/gir_ffi/info_ext/i_type_info.rb
|
151
151
|
- lib/gir_ffi/info_ext/i_field_info.rb
|
152
152
|
- lib/gir_ffi/info_ext/i_property_info.rb
|
153
|
+
- lib/gir_ffi/info_ext/i_registered_type_info.rb
|
153
154
|
- lib/gir_ffi/module_base.rb
|
154
155
|
- lib/gir_ffi/class_base.rb
|
155
156
|
- lib/gir_ffi/object_base.rb
|
@@ -169,6 +170,7 @@ files:
|
|
169
170
|
- lib/ffi-glib/list.rb
|
170
171
|
- lib/ffi-glib/hash_table.rb
|
171
172
|
- lib/ffi-glib/list_methods.rb
|
173
|
+
- lib/ffi-glib/strv.rb
|
172
174
|
- lib/ffi-glib/byte_array.rb
|
173
175
|
- lib/ffi-glib/ptr_array.rb
|
174
176
|
- lib/ffi-glib/s_list.rb
|