gir_ffi 0.0.8 → 0.0.9
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 +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
|