gir_ffi 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/TODO.rdoc +5 -0
- data/examples/01_empty_window.rb +0 -1
- data/examples/02_hello_world.rb +0 -1
- data/examples/03_upgraded_hello_world.rb +0 -1
- data/examples/04_webkit.rb +0 -1
- data/lib/gir_ffi/arg_helper.rb +231 -94
- data/lib/gir_ffi/builder/argument.rb +372 -46
- data/lib/gir_ffi/builder/module.rb +25 -10
- data/lib/gir_ffi/builder/type/constant.rb +39 -0
- data/lib/gir_ffi/builder/type/enum.rb +15 -5
- data/lib/gir_ffi/builder/type/registered_type.rb +25 -6
- data/lib/gir_ffi/builder/type/struct.rb +1 -9
- data/lib/gir_ffi/builder/type/union.rb +5 -0
- data/lib/gir_ffi/builder/type.rb +13 -14
- data/lib/gir_ffi/builder.rb +7 -4
- data/lib/gir_ffi/builder_helper.rb +4 -3
- data/lib/gir_ffi/i_base_info.rb +4 -0
- data/lib/gir_ffi/i_constant_info.rb +9 -0
- data/lib/gir_ffi/i_registered_type_info.rb +0 -1
- data/lib/gir_ffi/i_repository.rb +8 -2
- data/lib/gir_ffi/i_type_info.rb +7 -0
- data/lib/gir_ffi/lib.rb +41 -3
- data/lib/gir_ffi/overrides/glib.rb +188 -4
- data/lib/gir_ffi/overrides/gobject.rb +16 -5
- data/tasks/test.rake +1 -1
- data/test/arg_helper_test.rb +5 -5
- data/test/builder_test.rb +64 -41
- data/test/class_base_test.rb +1 -1
- data/test/function_definition_builder_test.rb +24 -2
- data/test/g_object_overrides_test.rb +1 -3
- data/test/g_object_test.rb +1 -1
- data/test/generated_gimarshallingtests_test.rb +1677 -0
- data/test/generated_gio_test.rb +1 -1
- data/test/generated_gtk_test.rb +31 -2
- data/test/generated_regress_test.rb +278 -54
- data/test/girffi_test.rb +20 -5
- data/test/glib_overrides_test.rb +81 -0
- data/test/gtk_overrides_test.rb +2 -3
- data/test/i_object_info_test.rb +1 -1
- data/test/i_repository_test.rb +3 -4
- data/test/lib/Makefile.am +18 -2
- data/test/module_builder_test.rb +1 -1
- data/test/test_helper.rb +88 -5
- data/test/type_builder_test.rb +7 -10
- metadata +16 -13
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.0.9 / 2011-05-02
|
2
|
+
|
3
|
+
* More complete support for the basic types.
|
4
|
+
* Improved support for GList, GSList, GStrv, and GValue.
|
5
|
+
* Add support for GHashTable, GVariant, GByteArray, and GArray.
|
6
|
+
* Generate constants.
|
7
|
+
* When setting up a module, set up its dependencies as well.
|
8
|
+
* Test against the GIMarshallingTests test namespace.
|
9
|
+
* Use minitest/spec for testing.
|
10
|
+
* Various bug fixes and internal improvements.
|
11
|
+
|
1
12
|
== 0.0.8 / 2011-04-08
|
2
13
|
|
3
14
|
* Generate modules with names starting with a lowercase letter (like
|
data/TODO.rdoc
CHANGED
@@ -28,6 +28,11 @@ two cases are not distinguished.
|
|
28
28
|
Update: generic pointers have been declared 'not introspectable', so
|
29
29
|
handling them can be removed.
|
30
30
|
|
31
|
+
== Handle fundamental objects that are not GObject.
|
32
|
+
|
33
|
+
This is a big one. See commit 1e9822c7817062a9b853269b9418fd78782090b5 in
|
34
|
+
gobject-introspection, and TestFundamentalObject in Regress.
|
35
|
+
|
31
36
|
== Check binding of GObject:
|
32
37
|
|
33
38
|
(11:37:03 PM) walters: the basic story is that GObject should be manually bound
|
data/examples/01_empty_window.rb
CHANGED
data/examples/02_hello_world.rb
CHANGED
data/examples/04_webkit.rb
CHANGED
data/lib/gir_ffi/arg_helper.rb
CHANGED
@@ -1,36 +1,44 @@
|
|
1
1
|
require 'gir_ffi/allocation_helper'
|
2
|
+
require 'gir_ffi/builder'
|
2
3
|
|
3
4
|
module GirFFI
|
4
5
|
module ArgHelper
|
6
|
+
SIMPLE_G_TYPES = [
|
7
|
+
:gint8, :gint16, :gint, :gint32, :gint64,
|
8
|
+
:guint8, :guint16, :guint32, :guint64,
|
9
|
+
:gfloat, :gdouble]
|
10
|
+
|
11
|
+
def self.setup_array_to_inptr_handler_for *types
|
12
|
+
types.flatten.each do |type|
|
13
|
+
ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
|
14
|
+
defn =
|
15
|
+
"def self.#{type}_array_to_inptr ary
|
16
|
+
return nil if ary.nil?
|
17
|
+
block = allocate_array_of_type #{ffi_type.inspect}, ary.length
|
18
|
+
block.put_array_of_#{ffi_type} 0, ary
|
19
|
+
end"
|
20
|
+
eval defn
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
setup_array_to_inptr_handler_for SIMPLE_G_TYPES
|
25
|
+
setup_array_to_inptr_handler_for :pointer
|
26
|
+
|
5
27
|
# FIXME: Hideous.
|
6
28
|
def self.object_to_inptr obj
|
7
29
|
return obj.to_ptr if obj.respond_to? :to_ptr
|
8
30
|
return nil if obj.nil?
|
31
|
+
return obj if obj.is_a? FFI::Pointer
|
9
32
|
FFI::Pointer.new(obj.object_id)
|
10
33
|
end
|
11
34
|
|
12
35
|
def self.typed_array_to_inptr type, ary
|
13
36
|
return nil if ary.nil?
|
37
|
+
return utf8_array_to_inptr ary if type == :utf8
|
14
38
|
block = allocate_array_of_type type, ary.length
|
15
39
|
block.send "put_array_of_#{type}", 0, ary
|
16
40
|
end
|
17
41
|
|
18
|
-
def self.int32_array_to_inptr ary
|
19
|
-
typed_array_to_inptr :int32, ary
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.int16_array_to_inptr ary
|
23
|
-
typed_array_to_inptr :int16, ary
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.int64_array_to_inptr ary
|
27
|
-
typed_array_to_inptr :int64, ary
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.int8_array_to_inptr ary
|
31
|
-
typed_array_to_inptr :int8, ary
|
32
|
-
end
|
33
|
-
|
34
42
|
def self.utf8_to_inptr str
|
35
43
|
return nil if str.nil?
|
36
44
|
len = str.bytesize
|
@@ -44,28 +52,17 @@ module GirFFI
|
|
44
52
|
typed_array_to_inptr :pointer, ptr_ary
|
45
53
|
end
|
46
54
|
|
47
|
-
|
48
|
-
|
49
|
-
when 4
|
50
|
-
int32_array_to_inptr ary
|
51
|
-
when 8
|
52
|
-
int64_array_to_inptr ary
|
53
|
-
else
|
54
|
-
raise RuntimeError, "Unexpected size of :size_t"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.gvalue_array_to_inptr ary
|
55
|
+
# FIXME: :interface is too generic. implement only GValueArray?
|
56
|
+
def self.interface_array_to_inptr ary
|
59
57
|
return nil if ary.nil?
|
60
58
|
raise NotImplementedError
|
61
59
|
end
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
alias gint64_array_to_inptr int64_array_to_inptr
|
61
|
+
def self.interface_pointer_array_to_inptr ary
|
62
|
+
return nil if ary.nil?
|
63
|
+
ptr_ary = ary.map {|ifc| ifc.to_ptr}
|
64
|
+
ptr_ary << nil
|
65
|
+
pointer_array_to_inptr ptr_ary
|
69
66
|
end
|
70
67
|
|
71
68
|
def self.cleanup_ptr ptr
|
@@ -87,8 +84,22 @@ module GirFFI
|
|
87
84
|
LibC.free ptr
|
88
85
|
end
|
89
86
|
|
90
|
-
def self.
|
91
|
-
|
87
|
+
def self.setup_type_to_inoutptr_handler_for *types
|
88
|
+
types.flatten.each do |type|
|
89
|
+
ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
|
90
|
+
defn =
|
91
|
+
"def self.#{type}_to_inoutptr val
|
92
|
+
#{type}_pointer.put_#{ffi_type} 0, val
|
93
|
+
end"
|
94
|
+
eval defn
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
setup_type_to_inoutptr_handler_for SIMPLE_G_TYPES
|
99
|
+
setup_type_to_inoutptr_handler_for :pointer
|
100
|
+
|
101
|
+
def self.gboolean_to_inoutptr val
|
102
|
+
gboolean_pointer.put_int 0, (val ? 1 : 0)
|
92
103
|
end
|
93
104
|
|
94
105
|
def self.utf8_to_inoutptr str
|
@@ -97,81 +108,81 @@ module GirFFI
|
|
97
108
|
end
|
98
109
|
|
99
110
|
def self.int32_array_to_inoutptr ary
|
100
|
-
block =
|
111
|
+
block = gint32_array_to_inptr ary
|
101
112
|
pointer_pointer.write_pointer block
|
102
113
|
end
|
103
114
|
|
104
115
|
def self.utf8_array_to_inoutptr ary
|
105
116
|
return nil if ary.nil?
|
106
|
-
|
107
|
-
ptrs = ary.map {|str| utf8_to_inptr str}
|
108
|
-
|
109
|
-
block = AllocationHelper.safe_malloc FFI.type_size(:pointer) * ptrs.length
|
110
|
-
block.write_array_of_pointer ptrs
|
111
|
-
|
112
|
-
pointer_pointer.write_pointer block
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.double_to_inoutptr val
|
116
|
-
double_pointer.put_double 0, val
|
117
|
+
pointer_pointer.write_pointer utf8_array_to_inptr(ary)
|
117
118
|
end
|
118
119
|
|
119
120
|
class << self
|
120
|
-
alias int_to_inoutptr int32_to_inoutptr
|
121
|
-
alias gint32_to_inoutptr int32_to_inoutptr
|
122
121
|
alias int_array_to_inoutptr int32_array_to_inoutptr
|
123
122
|
alias gint32_array_to_inoutptr int32_array_to_inoutptr
|
124
|
-
alias gdouble_to_inoutptr double_to_inoutptr
|
125
123
|
end
|
126
124
|
|
127
|
-
def self.
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
125
|
+
def self.setup_pointer_maker_for *types
|
126
|
+
types.flatten.each do |type|
|
127
|
+
ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
|
128
|
+
size = FFI.type_size ffi_type
|
129
|
+
defn =
|
130
|
+
"def self.#{type}_pointer
|
131
|
+
AllocationHelper.safe_malloc #{size}
|
132
|
+
end"
|
133
|
+
eval defn
|
134
|
+
end
|
133
135
|
end
|
134
136
|
|
135
|
-
|
136
|
-
|
137
|
-
end
|
137
|
+
setup_pointer_maker_for SIMPLE_G_TYPES
|
138
|
+
setup_pointer_maker_for :pointer
|
138
139
|
|
139
140
|
class << self
|
140
|
-
alias
|
141
|
-
alias gint32_pointer int32_pointer
|
142
|
-
alias gdouble_pointer double_pointer
|
141
|
+
alias gboolean_pointer gint_pointer
|
143
142
|
end
|
144
143
|
|
145
|
-
def self.
|
146
|
-
|
144
|
+
def self.setup_type_outptr_handler_for *types
|
145
|
+
types.flatten.each do |type|
|
146
|
+
ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
|
147
|
+
defn =
|
148
|
+
"def self.#{type}_outptr
|
149
|
+
#{type}_pointer.put_#{ffi_type} 0, 0
|
150
|
+
end"
|
151
|
+
eval defn
|
152
|
+
end
|
147
153
|
end
|
148
154
|
|
149
|
-
|
150
|
-
|
155
|
+
setup_type_outptr_handler_for SIMPLE_G_TYPES
|
156
|
+
|
157
|
+
def self.gboolean_outptr
|
158
|
+
gboolean_pointer.put_int 0, 0
|
151
159
|
end
|
152
160
|
|
153
161
|
def self.pointer_outptr
|
154
|
-
pointer_pointer.
|
162
|
+
pointer_pointer.put_pointer 0, nil
|
155
163
|
end
|
156
164
|
|
157
165
|
def self.utf8_outptr
|
158
166
|
pointer_outptr
|
159
167
|
end
|
160
168
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
169
|
+
def self.setup_outptr_to_type_handler_for *types
|
170
|
+
types.flatten.each do |type|
|
171
|
+
ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
|
172
|
+
defn =
|
173
|
+
"def self.outptr_to_#{type} ptr
|
174
|
+
ptr.get_#{ffi_type} 0
|
175
|
+
end"
|
176
|
+
eval defn
|
177
|
+
end
|
165
178
|
end
|
166
179
|
|
167
|
-
|
168
|
-
|
169
|
-
ptr.read_pointer
|
170
|
-
end
|
180
|
+
setup_outptr_to_type_handler_for SIMPLE_G_TYPES
|
181
|
+
setup_outptr_to_type_handler_for :pointer
|
171
182
|
|
172
|
-
# Converts an outptr to
|
173
|
-
def self.
|
174
|
-
ptr.
|
183
|
+
# Converts an outptr to a boolean.
|
184
|
+
def self.outptr_to_gboolean ptr
|
185
|
+
(ptr.get_int 0) != 0
|
175
186
|
end
|
176
187
|
|
177
188
|
# Converts an outptr to a string.
|
@@ -183,14 +194,7 @@ module GirFFI
|
|
183
194
|
def self.outptr_to_utf8_array ptr, size
|
184
195
|
block = ptr.read_pointer
|
185
196
|
return nil if block.null?
|
186
|
-
|
187
|
-
|
188
|
-
ptrs.map { |ptr| ptr_to_utf8 ptr }
|
189
|
-
end
|
190
|
-
|
191
|
-
# Converts an outptr to a double.
|
192
|
-
def self.outptr_to_double ptr
|
193
|
-
ptr.get_double 0
|
197
|
+
ptr_to_utf8_array block, size
|
194
198
|
end
|
195
199
|
|
196
200
|
# Converts an outptr to an array of int.
|
@@ -200,39 +204,144 @@ module GirFFI
|
|
200
204
|
ptr_to_int32_array block, size
|
201
205
|
end
|
202
206
|
|
207
|
+
# Converts an outptr to an array of the given class.
|
208
|
+
def self.outptr_to_interface_array klass, ptr, size
|
209
|
+
block = ptr.read_pointer
|
210
|
+
return nil if block.null?
|
211
|
+
ptr_to_interface_array klass, block, size
|
212
|
+
end
|
213
|
+
|
203
214
|
class << self
|
204
|
-
alias outptr_to_int outptr_to_int32
|
205
215
|
alias outptr_to_int_array outptr_to_int32_array
|
206
|
-
alias outptr_to_gint32 outptr_to_int32
|
207
216
|
alias outptr_to_gint32_array outptr_to_int32_array
|
208
|
-
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.ptr_to_typed_array type, ptr, size
|
220
|
+
if type == :utf8
|
221
|
+
ptr_to_utf8_array ptr, size
|
222
|
+
else
|
223
|
+
ptr.send "get_array_of_#{type}", 0, size
|
224
|
+
end
|
209
225
|
end
|
210
226
|
|
211
227
|
def self.ptr_to_int32_array ptr, size
|
212
228
|
ptr.get_array_of_int32(0, size)
|
213
229
|
end
|
214
230
|
|
215
|
-
def self.
|
216
|
-
ptr.
|
231
|
+
def self.ptr_to_int16_array ptr, size
|
232
|
+
ptr.get_array_of_int16(0, size)
|
233
|
+
end
|
234
|
+
|
235
|
+
def self.ptr_to_utf8_array ptr, size
|
236
|
+
ptrs = ptr.read_array_of_pointer(size)
|
237
|
+
|
238
|
+
ptrs.map { |ptr| ptr_to_utf8 ptr }
|
239
|
+
end
|
240
|
+
|
241
|
+
def self.ptr_to_interface_array klass, ptr, size
|
242
|
+
sz = klass.ffi_structure.size
|
243
|
+
arr = []
|
244
|
+
size.times do
|
245
|
+
arr << klass.wrap(ptr)
|
246
|
+
ptr += sz
|
247
|
+
end
|
248
|
+
arr
|
249
|
+
end
|
250
|
+
|
251
|
+
if RUBY_VERSION < "1.9"
|
252
|
+
def self.ptr_to_utf8 ptr
|
253
|
+
ptr.null? ? nil : ptr.read_string
|
254
|
+
end
|
255
|
+
else
|
256
|
+
def self.ptr_to_utf8 ptr
|
257
|
+
ptr.null? ? nil : ptr.read_string.force_encoding("utf-8")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.ptr_to_utf8_length ptr, len
|
262
|
+
ptr.null? ? nil : ptr.read_string(len)
|
217
263
|
end
|
218
264
|
|
219
265
|
class << self
|
220
266
|
alias ptr_to_int_array ptr_to_int32_array
|
221
267
|
alias ptr_to_gint32_array ptr_to_int32_array
|
268
|
+
alias ptr_to_gint16_array ptr_to_int16_array
|
269
|
+
end
|
270
|
+
|
271
|
+
# Set up gtype handlers depending on type size.
|
272
|
+
class << self
|
273
|
+
case FFI.type_size(:size_t)
|
274
|
+
when 4
|
275
|
+
alias gtype_array_to_inptr gint32_array_to_inptr
|
276
|
+
alias gtype_outptr gint32_outptr
|
277
|
+
alias gtype_to_inoutptr gint32_to_inoutptr
|
278
|
+
alias outptr_to_gtype outptr_to_gint32
|
279
|
+
when 8
|
280
|
+
alias gtype_array_to_inptr gint64_array_to_inptr
|
281
|
+
alias gtype_outptr gint64_outptr
|
282
|
+
alias gtype_to_inoutptr gint64_to_inoutptr
|
283
|
+
alias outptr_to_gtype outptr_to_gint64
|
284
|
+
else
|
285
|
+
raise RuntimeError, "Unexpected size of :size_t"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.outptr_strv_to_utf8_array ptr
|
290
|
+
strv_to_utf8_array ptr.read_pointer
|
291
|
+
end
|
292
|
+
|
293
|
+
def self.strv_to_utf8_array strv
|
294
|
+
return [] if strv.null?
|
295
|
+
arr = []
|
296
|
+
i = 0
|
297
|
+
loop do
|
298
|
+
ptr = strv.get_pointer i * FFI.type_size(:pointer)
|
299
|
+
break if ptr.null?
|
300
|
+
arr << ptr.read_string
|
301
|
+
i += 1
|
302
|
+
end
|
303
|
+
return arr
|
222
304
|
end
|
223
305
|
|
224
306
|
def self.utf8_array_to_glist arr
|
225
307
|
return nil if arr.nil?
|
226
|
-
arr.inject(
|
308
|
+
arr.inject(GLib.list_new :utf8) { |lst, str|
|
227
309
|
GLib.list_append lst, utf8_to_inptr(str) }
|
228
310
|
end
|
229
311
|
|
312
|
+
def self.gint32_array_to_glist arr
|
313
|
+
return nil if arr.nil?
|
314
|
+
arr.inject(GLib.list_new :gint32) { |lst, int|
|
315
|
+
GLib.list_append lst, cast_int32_to_pointer(int) }
|
316
|
+
end
|
317
|
+
|
230
318
|
def self.utf8_array_to_gslist arr
|
231
319
|
return nil if arr.nil?
|
232
|
-
arr.reverse.inject(
|
320
|
+
arr.reverse.inject(GLib.slist_new :utf8) { |lst, str|
|
233
321
|
GLib.slist_prepend lst, utf8_to_inptr(str) }
|
234
322
|
end
|
235
323
|
|
324
|
+
def self.gint32_array_to_gslist arr
|
325
|
+
return nil if arr.nil?
|
326
|
+
arr.reverse.inject(GLib.slist_new :gint32) { |lst, int|
|
327
|
+
GLib.slist_prepend lst, cast_int32_to_pointer(int) }
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.hash_to_ghash keytype, valtype, hash
|
331
|
+
return nil if hash.nil?
|
332
|
+
ghash = GLib.hash_table_new keytype, valtype
|
333
|
+
hash.each do |key, val|
|
334
|
+
ghash.insert key, val
|
335
|
+
end
|
336
|
+
ghash
|
337
|
+
end
|
338
|
+
|
339
|
+
def self.void_array_to_gslist ary
|
340
|
+
return nil if ary.nil?
|
341
|
+
return ary if ary.is_a? GLib::SList
|
342
|
+
raise NotImplementedError
|
343
|
+
end
|
344
|
+
|
236
345
|
def self.glist_to_utf8_array ptr
|
237
346
|
return [] if ptr.null?
|
238
347
|
# FIXME: Quasi-circular dependency on generated module
|
@@ -267,6 +376,7 @@ module GirFFI
|
|
267
376
|
map_single_callback_arg arg, inf }
|
268
377
|
end
|
269
378
|
|
379
|
+
# TODO: Use GirFFI::ReturnValue classes for mapping.
|
270
380
|
def self.map_single_callback_arg arg, info
|
271
381
|
case info.argument_type.tag
|
272
382
|
when :interface
|
@@ -333,5 +443,32 @@ module GirFFI
|
|
333
443
|
def self.gir
|
334
444
|
gir = GirFFI::IRepository.default
|
335
445
|
end
|
446
|
+
|
447
|
+
def self.cast_from_pointer type, it
|
448
|
+
case type
|
449
|
+
when :utf8, :filename
|
450
|
+
ptr_to_utf8 it
|
451
|
+
when :gint32
|
452
|
+
cast_pointer_to_int32 it
|
453
|
+
else
|
454
|
+
it.address
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def self.cast_uint32_to_int32 val
|
459
|
+
if val >= 0x80000000
|
460
|
+
-(0x100000000-val)
|
461
|
+
else
|
462
|
+
val
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
def self.cast_pointer_to_int32 ptr
|
467
|
+
cast_uint32_to_int32(ptr.address & 0xffffffff)
|
468
|
+
end
|
469
|
+
|
470
|
+
def self.cast_int32_to_pointer int
|
471
|
+
FFI::Pointer.new(int)
|
472
|
+
end
|
336
473
|
end
|
337
474
|
end
|