gir_ffi 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|