gir_ffi 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/History.txt +11 -0
  2. data/README.rdoc +28 -14
  3. data/Rakefile +1 -1
  4. data/TODO.rdoc +3 -24
  5. data/examples/05_notification.rb +35 -0
  6. data/lib/gir_ffi/arg_helper.rb +15 -279
  7. data/lib/gir_ffi/builder/argument/base.rb +110 -0
  8. data/lib/gir_ffi/builder/argument/hash_table_base.rb +20 -0
  9. data/lib/gir_ffi/builder/argument/in_base.rb +19 -0
  10. data/lib/gir_ffi/builder/argument/in_out_base.rb +25 -0
  11. data/lib/gir_ffi/builder/argument/list_base.rb +16 -0
  12. data/lib/gir_ffi/builder/argument/out_base.rb +27 -0
  13. data/lib/gir_ffi/builder/argument.rb +167 -357
  14. data/lib/gir_ffi/builder/function.rb +2 -0
  15. data/lib/gir_ffi/builder/module.rb +2 -2
  16. data/lib/gir_ffi/builder/type/base.rb +7 -0
  17. data/lib/gir_ffi/builder/type/callback.rb +1 -8
  18. data/lib/gir_ffi/builder/type/constant.rb +1 -6
  19. data/lib/gir_ffi/builder/type/enum.rb +2 -7
  20. data/lib/gir_ffi/builder/type/interface.rb +12 -14
  21. data/lib/gir_ffi/builder/type/object.rb +32 -13
  22. data/lib/gir_ffi/builder/type/registered_type.rb +1 -78
  23. data/lib/gir_ffi/builder/type/struct.rb +2 -0
  24. data/lib/gir_ffi/builder/type/struct_based.rb +9 -24
  25. data/lib/gir_ffi/builder/type/unintrospectable.rb +63 -0
  26. data/lib/gir_ffi/builder/type/union.rb +8 -7
  27. data/lib/gir_ffi/builder/type/with_layout.rb +43 -0
  28. data/lib/gir_ffi/builder/type/with_methods.rb +61 -0
  29. data/lib/gir_ffi/builder.rb +39 -0
  30. data/lib/gir_ffi/callback_helper.rb +58 -0
  31. data/lib/gir_ffi/class_base.rb +17 -5
  32. data/lib/gir_ffi/i_repository.rb +0 -4
  33. data/lib/gir_ffi/in_out_pointer.rb +76 -0
  34. data/lib/gir_ffi/in_pointer.rb +46 -0
  35. data/lib/gir_ffi/interface_base.rb +12 -0
  36. data/lib/gir_ffi/module_base.rb +7 -3
  37. data/lib/gir_ffi/overrides/glib.rb +14 -3
  38. data/lib/gir_ffi/overrides/gobject.rb +37 -15
  39. data/lib/gir_ffi/overrides/gtk.rb +1 -1
  40. data/lib/gir_ffi/version.rb +1 -1
  41. data/lib/gir_ffi.rb +3 -0
  42. data/tasks/rdoc.rake +6 -0
  43. data/tasks/test.rake +22 -3
  44. data/tasks/yardoc.rake +6 -0
  45. data/test/arg_helper_test.rb +2 -72
  46. data/test/builder_test.rb +15 -19
  47. data/test/function_definition_builder_test.rb +30 -37
  48. data/test/g_object_overrides_test.rb +29 -1
  49. data/test/glib_overrides_test.rb +4 -0
  50. data/test/gtk_overrides_test.rb +21 -15
  51. data/test/i_repository_test.rb +2 -1
  52. data/test/{generated_gimarshallingtests_test.rb → integration/generated_gimarshallingtests_test.rb} +1 -1
  53. data/test/integration/generated_gio_test.rb +98 -0
  54. data/test/integration/generated_gobject_test.rb +30 -0
  55. data/test/{generated_gtk_test.rb → integration/generated_gtk_test.rb} +5 -5
  56. data/test/{generated_regress_test.rb → integration/generated_regress_test.rb} +19 -5
  57. data/test/interface_type_builder_test.rb +1 -1
  58. data/test/module_builder_test.rb +3 -3
  59. data/test/test_helper.rb +4 -9
  60. data/test/type_builder_test.rb +5 -5
  61. data/test/{dynamic_type_builder_test.rb → unintrospectable_type_builder_test.rb} +12 -8
  62. data/test/unit/builder_test.rb +31 -0
  63. data/test/unit/callback_helper_test.rb +19 -0
  64. data/test/unit/constant_builder_test.rb +5 -0
  65. data/test/unit/i_constant_info_test.rb +17 -0
  66. data/test/unit/in_out_pointer_test.rb +118 -0
  67. data/test/unit/in_pointer_test.rb +69 -0
  68. data/test/unit/object_type_builder_test.rb +20 -0
  69. metadata +47 -19
  70. data/lib/gir_ffi/builder/dynamic_type.rb +0 -41
  71. data/test/generated_gio_test.rb +0 -39
  72. data/test/generated_gobject_test.rb +0 -15
  73. data/test/object_type_builder_test.rb +0 -34
@@ -1,124 +1,25 @@
1
- module GirFFI::Builder
2
- # Abstract parent class of the argument building classes. These classes
3
- # are used by Builder::Function to create the code that processes
4
- # each argument before and after the actual function call.
5
- class Argument
6
- KEYWORDS = [
7
- "alias", "and", "begin", "break", "case", "class", "def", "do",
8
- "else", "elsif", "end", "ensure", "false", "for", "if", "in",
9
- "module", "next", "nil", "not", "or", "redo", "rescue", "retry",
10
- "return", "self", "super", "then", "true", "undef", "unless",
11
- "until", "when", "while", "yield"
12
- ]
13
-
14
- attr_reader :callarg, :name, :retname
15
-
16
- attr_accessor :length_arg, :array_arg
17
-
18
- def initialize function_builder, arginfo=nil, libmodule=nil
19
- @arginfo = arginfo
20
- @inarg = nil
21
- @callarg = nil
22
- @retname = nil
23
- @name = nil
24
- @function_builder = function_builder
25
- @libmodule = libmodule
26
- @length_arg = nil
27
- @array_arg = nil
28
- end
29
-
30
- def self.build function_builder, arginfo, libmodule
31
- klass = case arginfo.direction
32
- when :inout
33
- InOutArgument
34
- when :in
35
- InArgument
36
- when :out
37
- OutArgument
38
- else
39
- raise ArgumentError
40
- end
41
- klass.build function_builder, arginfo, libmodule
42
- end
43
-
44
- def type_info
45
- @arginfo.argument_type
46
- end
47
-
48
- def type_tag
49
- tag = type_info.tag
50
- tag == :GType ? :gtype : tag
51
- end
52
-
53
- def subtype_tag index=0
54
- st = type_info.param_type(index)
55
- t = st.tag
56
- case t
57
- when :GType
58
- return :gtype
59
- when :interface
60
- return :interface_pointer if st.pointer?
61
- return :interface
62
- else
63
- return t
64
- end
65
- end
66
-
67
- def argument_class_name
68
- iface = type_info.interface
69
- "::#{iface.safe_namespace}::#{iface.name}"
70
- end
1
+ require 'gir_ffi/in_pointer'
2
+ require 'gir_ffi/in_out_pointer'
71
3
 
72
- def subtype_class_name index=0
73
- iface = type_info.param_type(index).interface
74
- "::#{iface.safe_namespace}::#{iface.name}"
75
- end
76
-
77
- def array_size
78
- if @length_arg
79
- @length_arg.retname
80
- else
81
- type_info.array_fixed_size
82
- end
83
- end
4
+ require 'gir_ffi/builder/argument/base'
5
+ require 'gir_ffi/builder/argument/in_base'
6
+ require 'gir_ffi/builder/argument/out_base'
7
+ require 'gir_ffi/builder/argument/in_out_base'
8
+ require 'gir_ffi/builder/argument/list_base'
9
+ require 'gir_ffi/builder/argument/hash_table_base'
84
10
 
85
- def safe name
86
- if KEYWORDS.include? name
87
- "#{name}_"
88
- else
89
- name
90
- end
91
- end
92
-
93
- def inarg
94
- @array_arg.nil? ? @inarg : nil
95
- end
96
-
97
- def retval
98
- @array_arg.nil? ? @retname : nil
99
- end
100
-
101
- def pre
102
- []
103
- end
104
-
105
- def post
106
- []
107
- end
108
-
109
- def postpost
110
- []
11
+ module GirFFI::Builder
12
+ module Argument
13
+ def self.build function_builder, arginfo, libmodule
14
+ {
15
+ :inout => InOutArgument,
16
+ :in => InArgument,
17
+ :out => OutArgument
18
+ }[arginfo.direction].build function_builder, arginfo, libmodule
111
19
  end
112
20
  end
113
21
 
114
- # Implements argument processing for arguments with direction :in.
115
- class InArgument < Argument
116
- def prepare
117
- @name = safe(@arginfo.name)
118
- @callarg = @function_builder.new_var
119
- @inarg = @name
120
- end
121
-
22
+ module InArgument
122
23
  def self.build function_builder, arginfo, libmodule
123
24
  type = arginfo.argument_type
124
25
  klass = case type.tag
@@ -151,100 +52,78 @@ module GirFFI::Builder
151
52
 
152
53
  # Implements argument processing for callback arguments with direction
153
54
  # :in.
154
- class CallbackInArgument < InArgument
55
+ class CallbackInArgument < Argument::InBase
155
56
  def pre
156
57
  iface = type_info.interface
157
- [ "#{@callarg} = GirFFI::ArgHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@name}",
158
- "::#{@libmodule}::CALLBACKS << #{@callarg}" ]
58
+ [ "#{callarg} = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@name}",
59
+ "::#{@libmodule}::CALLBACKS << #{callarg}" ]
159
60
  end
160
61
  end
161
62
 
162
63
  # Implements argument processing for void pointer arguments with
163
64
  # direction :in.
164
- class VoidInArgument < InArgument
65
+ class VoidInArgument < Argument::InBase
165
66
  def pre
166
- [ "#{@callarg} = GirFFI::ArgHelper.object_to_inptr #{@name}" ]
67
+ [ "#{callarg} = GirFFI::ArgHelper.object_to_inptr #{@name}" ]
167
68
  end
168
69
  end
169
70
 
170
71
  # Implements argument processing for array arguments with direction :in.
171
- class CArrayInArgument < InArgument
172
- def post
173
- unless @arginfo.ownership_transfer == :everything
174
- if subtype_tag == :utf8
175
- [ "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}" ]
176
- else
177
- [ "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
178
- end
179
- end
180
- end
181
-
72
+ class CArrayInArgument < Argument::InBase
182
73
  def pre
183
74
  pr = []
184
75
  size = type_info.array_fixed_size
185
76
  if size > -1
186
77
  pr << "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
187
78
  end
188
- pr << "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inptr #{@name}"
79
+ pr << "#{callarg} = GirFFI::InPointer.from_array #{subtype_tag.inspect}, #{@name}"
189
80
  pr
190
81
  end
191
82
  end
192
83
 
193
84
  # Implements argument processing for glist and gslist arguments with
194
85
  # direction :in.
195
- class ListInArgument < InArgument
86
+ class ListInArgument < Argument::InBase
196
87
  def pre
197
- [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name}" ]
88
+ [ "#{callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name}" ]
198
89
  end
199
90
  end
200
91
 
201
92
  # Implements argument processing for ghash arguments with direction :in.
202
- class HashTableInArgument < InArgument
93
+ class HashTableInArgument < Argument::InBase
203
94
  def pre
204
- [ "#{@callarg} = GirFFI::ArgHelper.hash_to_ghash #{subtype_tag(0).inspect}, #{subtype_tag(1).inspect}, #{@name}" ]
95
+ [ "#{callarg} = GirFFI::ArgHelper.hash_to_ghash #{subtype_tag(0).inspect}, #{subtype_tag(1).inspect}, #{@name}" ]
205
96
  end
206
97
  end
207
98
 
208
99
  # Implements argument processing for UTF8 string arguments with direction
209
100
  # :in.
210
- class Utf8InArgument < InArgument
101
+ class Utf8InArgument < Argument::InBase
211
102
  def pre
212
- [ "#{@callarg} = GirFFI::ArgHelper.utf8_to_inptr #{@name}" ]
213
- end
214
-
215
- def post
216
- # TODO: Write tests and enable this.
217
- # [ "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
218
- []
103
+ [ "#{callarg} = GirFFI::InPointer.from :utf8, #{@name}" ]
219
104
  end
220
105
  end
221
106
 
222
107
  # Implements argument processing for arguments with direction :in whose
223
108
  # type-specific processing is left to FFI (e.g., ints and floats, and
224
109
  # objects that implement to_ptr.).
225
- class RegularInArgument < InArgument
110
+ class RegularInArgument < Argument::InBase
226
111
  def pre
227
112
  pr = []
228
113
  if @array_arg
229
114
  arrname = @array_arg.name
230
115
  pr << "#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length"
231
116
  end
232
- pr << "#{@callarg} = #{@name}"
117
+ pr << "#{callarg} = #{@name}"
233
118
  pr
234
119
  end
235
120
  end
236
121
 
237
122
  # Implements argument processing for arguments with direction :out.
238
- class OutArgument < Argument
239
- def prepare
240
- @name = safe(@arginfo.name)
241
- @callarg = @function_builder.new_var
242
- @retname = @function_builder.new_var
243
- end
244
-
123
+ module OutArgument
245
124
  def self.build function_builder, arginfo, libmodule
246
125
  type = arginfo.argument_type
247
- klass = case arginfo.argument_type.tag
126
+ klass = case type.tag
248
127
  when :interface
249
128
  case type.interface.info_type
250
129
  when :enum, :flags
@@ -276,177 +155,133 @@ module GirFFI::Builder
276
155
  end
277
156
  end
278
157
 
158
+ # Implements argument processing for arguments with direction
159
+ # :out that are neither arrays nor 'interfaces'.
160
+ class RegularOutArgument < Argument::OutBase
161
+ def post
162
+ [ "#{retname} = #{callarg}.to_value" ]
163
+ end
164
+
165
+ private
166
+
167
+ def base_type
168
+ type_tag
169
+ end
170
+ end
171
+
279
172
  # Implements argument processing for arguments with direction
280
173
  # :out that are enums
281
- class EnumOutArgument < OutArgument
174
+ class EnumOutArgument < RegularOutArgument
282
175
  def post
283
- pst = [ "#{@retname} = #{argument_class_name}[GirFFI::ArgHelper.outptr_to_gint32 #{@callarg}]" ]
284
- if @arginfo.ownership_transfer == :everything
285
- pst << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
286
- end
287
- pst
176
+ [ "#{retname} = #{argument_class_name}[#{callarg}.to_value]" ]
288
177
  end
289
178
 
290
- def pre
291
- [ "#{@callarg} = GirFFI::ArgHelper.gint32_outptr" ]
179
+ private
180
+
181
+ def base_type
182
+ :gint32
292
183
  end
293
184
  end
294
185
 
295
186
  # Implements argument processing for interface arguments with direction
296
187
  # :out (structs, objects, etc.).
297
- class InterfaceOutArgument < OutArgument
188
+ class InterfaceOutArgument < Argument::OutBase
298
189
  def pre
299
190
  if @arginfo.caller_allocates?
300
- [ "#{@callarg} = #{argument_class_name}.allocate" ]
191
+ [ "#{callarg} = #{argument_class_name}.allocate" ]
301
192
  else
302
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
193
+ [ "#{callarg} = GirFFI::InOutPointer.for :pointer" ]
303
194
  end
304
195
  end
305
196
 
306
197
  def post
307
198
  if @arginfo.caller_allocates?
308
- [ "#{@retname} = #{@callarg}" ]
199
+ [ "#{retname} = #{callarg}" ]
309
200
  else
310
- [ "#{@retname} = #{argument_class_name}.wrap GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
201
+ [ "#{retname} = #{argument_class_name}.wrap #{callarg}.to_value" ]
311
202
  end
312
203
  end
313
204
  end
314
205
 
315
- # Implements argument processing for array arguments with direction
316
- # :out.
317
- class CArrayOutArgument < OutArgument
318
- def pre
319
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
206
+ # Base class for arguments with direction :out for which the base type is
207
+ # a pointer: For these, a pointer to a pointer needs to be passed to the
208
+ # C function.
209
+ class PointerLikeOutArgument < Argument::OutBase
210
+ private
211
+
212
+ def base_type
213
+ :pointer
320
214
  end
215
+ end
321
216
 
217
+ # Implements argument processing for array arguments with direction
218
+ # :out.
219
+ class CArrayOutArgument < PointerLikeOutArgument
322
220
  def postpost
323
- size = array_size
324
221
  tag = subtype_tag
325
222
 
326
- pp = []
327
-
223
+ args = [callarg, array_size]
328
224
  if tag == :interface or tag == :interface_pointer
329
- pp << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{subtype_class_name}, #{@callarg}, #{size}"
330
- else
331
- pp << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}"
332
- end
333
-
334
- if @arginfo.ownership_transfer == :everything
335
- case tag
336
- when :utf8
337
- pp << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{size}"
338
- when :interface
339
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
340
- else
341
- pp << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
342
- end
225
+ args.unshift subtype_class_name
343
226
  end
344
227
 
345
- pp
228
+ [ "#{retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{args.join ', '}" ]
346
229
  end
347
230
  end
348
231
 
349
232
  # Implements argument processing for strv arguments with direction
350
233
  # :out.
351
- class StrvOutArgument < OutArgument
352
- def pre
353
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
354
- end
355
-
356
- def postpost
357
- [ "#{@retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{@callarg}" ]
234
+ class StrvOutArgument < PointerLikeOutArgument
235
+ def post
236
+ [ "#{retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{callarg}" ]
358
237
  end
359
238
  end
360
239
 
361
240
  # Implements argument processing for GArray arguments with direction
362
241
  # :out.
363
- class ArrayOutArgument < OutArgument
364
- def pre
365
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
366
- end
242
+ class ArrayOutArgument < PointerLikeOutArgument
243
+ include Argument::ListBase
367
244
 
368
245
  def post
369
- tag = subtype_tag
370
- etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
371
-
372
246
  pp = []
373
-
374
- pp << "#{@retname} = GLib::Array.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})"
375
- pp << "#{@retname}.element_type = #{etype.inspect}"
376
-
377
- if @arginfo.ownership_transfer == :everything
378
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
379
- end
380
-
247
+ pp << "#{retname} = GLib::Array.wrap #{callarg}.to_value"
248
+ pp << "#{retname}.element_type = #{elm_t}"
381
249
  pp
382
250
  end
383
251
  end
384
252
 
385
253
  # Implements argument processing for glist arguments with direction
386
254
  # :out.
387
- class ListOutArgument < OutArgument
388
- def pre
389
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
390
- end
255
+ class ListOutArgument < PointerLikeOutArgument
256
+ include Argument::ListBase
391
257
 
392
258
  def post
393
- elm_t = subtype_tag.inspect
394
- [ "#{@retname} = GLib::List.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
259
+ [ "#{retname} = GLib::List.wrap #{elm_t}, #{callarg}.to_value" ]
395
260
  end
396
261
  end
397
262
 
398
263
  # Implements argument processing for gslist arguments with direction
399
264
  # :out.
400
- class SListOutArgument < OutArgument
401
- def pre
402
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
403
- end
265
+ class SListOutArgument < PointerLikeOutArgument
266
+ include Argument::ListBase
404
267
 
405
268
  def post
406
- elm_t = subtype_tag.inspect
407
- [ "#{@retname} = GLib::SList.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
269
+ [ "#{retname} = GLib::SList.wrap #{elm_t}, #{callarg}.to_value" ]
408
270
  end
409
271
  end
410
272
 
411
273
  # Implements argument processing for ghash arguments with direction
412
274
  # :out.
413
- class HashTableOutArgument < OutArgument
414
- def pre
415
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
416
- end
275
+ class HashTableOutArgument < PointerLikeOutArgument
276
+ include Argument::HashTableBase
417
277
 
418
- def postpost
419
- key_t = subtype_tag(0).inspect
420
- val_t = subtype_tag(1).inspect
421
- [ "#{@retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
422
- end
423
- end
424
-
425
- # Implements argument processing for arguments with direction
426
- # :out that are neither arrays nor 'interfaces'.
427
- class RegularOutArgument < OutArgument
428
278
  def post
429
- pst = [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{type_tag} #{@callarg}" ]
430
- if @arginfo.ownership_transfer == :everything
431
- pst << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
432
- end
433
- pst
434
- end
435
-
436
- def pre
437
- [ "#{@callarg} = GirFFI::ArgHelper.#{type_tag}_outptr" ]
279
+ [ "#{retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, #{callarg}.to_value" ]
438
280
  end
439
281
  end
440
282
 
441
283
  # Implements argument processing for arguments with direction :inout.
442
- class InOutArgument < Argument
443
- def prepare
444
- @name = safe(@arginfo.name)
445
- @callarg = @function_builder.new_var
446
- @inarg = @name
447
- @retname = @function_builder.new_var
448
- end
449
-
284
+ module InOutArgument
450
285
  def self.build function_builder, arginfo, libmodule
451
286
  type = arginfo.argument_type
452
287
  klass = case type.tag
@@ -484,167 +319,145 @@ module GirFFI::Builder
484
319
 
485
320
  # Implements argument processing for arguments with direction
486
321
  # :inout that are enums.
487
- class EnumInOutArgument < InOutArgument
322
+ class EnumInOutArgument < Argument::InOutBase
488
323
  def pre
489
324
  pr = []
490
- pr << "#{@callarg} = GirFFI::ArgHelper.gint32_to_inoutptr #{argument_class_name}[#{@name}]"
325
+ pr << "#{callarg} = GirFFI::InOutPointer.from :gint32, #{argument_class_name}[#{@name}]"
491
326
  pr
492
327
  end
493
328
 
494
329
  def post
495
- [ "#{@retname} = #{argument_class_name}[GirFFI::ArgHelper.outptr_to_gint32 #{@callarg}]",
496
- "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
330
+ [ "#{retname} = #{argument_class_name}[#{callarg}.to_value]" ]
497
331
  end
498
332
  end
499
333
 
500
334
  # Implements argument processing for interface arguments with direction
501
335
  # :inout (structs, objects, etc.).
502
- class InterfaceInOutArgument < InOutArgument
336
+ class InterfaceInOutArgument < Argument::InOutBase
503
337
  def pre
504
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr #{@name}.to_ptr" ]
338
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{@name}.to_ptr" ]
505
339
  end
506
340
 
507
341
  def post
508
- [ "#{@retname} = #{argument_class_name}.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})",
509
- "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
342
+ [ "#{retname} = #{argument_class_name}.wrap(#{callarg}.to_value)" ]
510
343
  end
511
344
  end
512
345
 
513
346
  # Implements argument processing for strv arguments with direction
514
347
  # :inout.
515
- class StrvInOutArgument < InOutArgument
348
+ class StrvInOutArgument < Argument::InOutBase
516
349
  def pre
517
- [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inoutptr #{@name}" ]
350
+ [ "#{callarg} = GirFFI::InOutPointer.from_array #{subtype_tag.inspect}, #{@name}" ]
518
351
  end
519
352
 
520
353
  def post
521
- [ "#{@retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{@callarg}" ]
354
+ [ "#{retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{callarg}" ]
522
355
  end
523
356
  end
524
357
 
525
358
  # Implements argument processing for array arguments with direction
526
359
  # :inout.
527
- class CArrayInOutArgument < InOutArgument
360
+ class CArrayInOutArgument < Argument::InOutBase
528
361
  def pre
529
- [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inoutptr #{@name}" ]
362
+ [ "#{callarg} = GirFFI::InOutPointer.from_array #{subtype_tag.inspect}, #{@name}" ]
530
363
  end
531
364
 
532
365
  def postpost
533
366
  tag = subtype_tag
534
367
  size = array_size
535
- pst = [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}" ]
536
- if @arginfo.ownership_transfer == :nothing
537
- pst << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
538
- else
539
- if tag == :utf8
540
- pst << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{size}"
541
- else
542
- pst << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
543
- end
544
- end
368
+ pst = [ "#{retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{callarg}, #{size}" ]
545
369
  pst
546
370
  end
371
+
547
372
  end
548
373
 
549
374
  # Implements argument processing for GArray arguments with direction
550
- # :out.
551
- class ArrayInOutArgument < InOutArgument
375
+ # :inout.
376
+ class ArrayInOutArgument < Argument::InOutBase
377
+ include Argument::ListBase
378
+
552
379
  def pre
553
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr #{@name}" ]
380
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{@name}" ]
554
381
  end
555
382
 
556
383
  def post
557
- tag = subtype_tag
558
- etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
559
-
560
384
  pp = []
561
-
562
- pp << "#{@retname} = GLib::Array.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})"
563
- pp << "#{@retname}.element_type = #{etype.inspect}"
564
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
565
-
385
+ pp << "#{retname} = GLib::Array.wrap(#{callarg}.to_value)"
386
+ pp << "#{retname}.element_type = #{elm_t}"
566
387
  pp
567
388
  end
568
389
  end
569
390
 
570
391
  # Implements argument processing for glist arguments with direction
571
392
  # :inout.
572
- class ListInOutArgument < InOutArgument
393
+ class ListInOutArgument < Argument::InOutBase
394
+ include Argument::ListBase
395
+
573
396
  def pre
574
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name})" ]
397
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag}(#{@name})" ]
575
398
  end
576
399
 
577
400
  def post
578
- elm_t = subtype_tag.inspect
579
- pp = []
580
- pp << "#{@retname} = GLib::List.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
581
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
582
- pp
401
+ [ "#{retname} = GLib::List.wrap #{elm_t}, #{callarg}.to_value" ]
583
402
  end
584
403
  end
585
404
 
586
405
  # Implements argument processing for gslist arguments with direction
587
406
  # :inout.
588
407
  # FIXME: Merge code with ListInOutArgument somehow.
589
- class SListInOutArgument < InOutArgument
408
+ class SListInOutArgument < Argument::InOutBase
409
+ include Argument::ListBase
410
+
590
411
  def pre
591
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name})" ]
412
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag}(#{@name})" ]
592
413
  end
593
414
 
594
415
  def post
595
- elm_t = subtype_tag.inspect
596
- pp = []
597
- pp << "#{@retname} = GLib::SList.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
598
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
599
- pp
416
+ [ "#{retname} = GLib::SList.wrap #{elm_t}, #{callarg}.to_value" ]
600
417
  end
601
418
  end
602
419
 
603
420
  # Implements argument processing for ghash arguments with direction
604
421
  # :inout.
605
- class HashTableInOutArgument < InOutArgument
422
+ class HashTableInOutArgument < Argument::InOutBase
423
+ include Argument::HashTableBase
424
+
606
425
  def pre
607
- key_t = subtype_tag(0).inspect
608
- val_t = subtype_tag(1).inspect
609
- [ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.hash_to_ghash(#{key_t}, #{val_t}, #{@name}))" ]
426
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GirFFI::ArgHelper.hash_to_ghash(#{key_t}, #{val_t}, #{@name})" ]
610
427
  end
611
428
 
612
- def postpost
613
- pp = []
614
-
615
- key_t = subtype_tag(0).inspect
616
- val_t = subtype_tag(1).inspect
617
- pp << "#{@retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
618
- pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
619
- pp
429
+ def post
430
+ [ "#{retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, #{callarg}.to_value" ]
620
431
  end
621
432
  end
622
433
 
623
434
  # Implements argument processing for arguments with direction
624
435
  # :inout that are neither arrays nor 'interfaces'.
625
- class RegularInOutArgument < InOutArgument
436
+ class RegularInOutArgument < Argument::InOutBase
626
437
  def pre
627
438
  pr = []
628
439
  if @array_arg
629
440
  pr << "#{@name} = #{@array_arg.name}.length"
630
441
  end
631
- pr << "#{@callarg} = GirFFI::ArgHelper.#{type_tag}_to_inoutptr #{@name}"
442
+ pr << "#{callarg} = GirFFI::InOutPointer.from #{type_tag.inspect}, #{@name}"
632
443
  pr
633
444
  end
634
445
 
635
446
  def post
636
- [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{type_tag} #{@callarg}",
637
- "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
447
+ [ "#{retname} = #{callarg}.to_value" ]
638
448
  end
639
449
  end
640
450
 
641
451
  # Implements argument processing for return values.
642
- class ReturnValue < Argument
452
+ class ReturnValue < Argument::Base
643
453
  attr_reader :cvar
644
454
 
645
- def prepare
646
- @cvar = @function_builder.new_var
647
- @retname = @function_builder.new_var
455
+ def cvar
456
+ @cvar ||= @function_builder.new_var
457
+ end
458
+
459
+ def retname
460
+ @retname ||= @function_builder.new_var
648
461
  end
649
462
 
650
463
  def type_info
@@ -699,36 +512,32 @@ module GirFFI::Builder
699
512
  end
700
513
  end
701
514
 
702
- # Null object to represent the case where no actual values is returned.
515
+ # Null object to represent the case where no actual value is returned.
703
516
  class VoidReturnValue < ReturnValue
704
- def prepare; end
517
+ def cvar; end
518
+ def retname; end
705
519
  end
706
520
 
707
521
  # Implements argument processing for interface return values (interfaces
708
522
  # and structs, but not objects, which need special handling for
709
- # polymorphism and constructors.
523
+ # polymorphism and constructors).
710
524
  class InterfaceReturnValue < ReturnValue
711
525
  def post
712
- [ "#{@retname} = #{argument_class_name}.wrap(#{@cvar})" ]
526
+ [ "#{retname} = #{argument_class_name}.wrap(#{cvar})" ]
713
527
  end
714
528
  end
715
529
 
716
530
  # Implements argument processing for object return values.
717
531
  class ObjectReturnValue < ReturnValue
718
532
  def post
719
- [ "#{@retname} = GirFFI::ArgHelper.object_pointer_to_object(#{@cvar})" ]
533
+ [ "#{retname} = GirFFI::ArgHelper.object_pointer_to_object(#{cvar})" ]
720
534
  end
721
535
  end
722
536
 
723
537
  # Implements argument processing for object constructors.
724
538
  class ConstructorReturnValue < ReturnValue
725
- def defining_class_name
726
- classinfo = @arginfo.container
727
- "::#{classinfo.namespace}::#{classinfo.name}"
728
- end
729
-
730
539
  def post
731
- [ "#{@retname} = self.constructor_wrap(#{@cvar})" ]
540
+ [ "#{retname} = self.constructor_wrap(#{cvar})" ]
732
541
  end
733
542
  end
734
543
 
@@ -737,56 +546,58 @@ module GirFFI::Builder
737
546
  def post
738
547
  size = array_size
739
548
 
740
- [ "#{@retname} = GirFFI::ArgHelper.ptr_to_#{subtype_tag}_array #{@cvar}, #{size}" ]
549
+ [ "#{retname} = GirFFI::ArgHelper.ptr_to_#{subtype_tag}_array #{cvar}, #{size}" ]
741
550
  end
742
551
  end
743
552
 
744
553
  # Implements argument processing for NULL-terminated string array return values.
745
554
  class StrvReturnValue < ReturnValue
746
555
  def post
747
- [ "#{@retname} = GirFFI::ArgHelper.strv_to_utf8_array #{@cvar}" ]
556
+ [ "#{retname} = GirFFI::ArgHelper.strv_to_utf8_array #{cvar}" ]
748
557
  end
749
558
  end
750
559
 
751
560
  # Implements argument processing for GList return values.
752
561
  class ListReturnValue < ReturnValue
562
+ include Argument::ListBase
563
+
753
564
  def post
754
- elm_t = subtype_tag.inspect
755
- [ "#{@retname} = GLib::List.wrap(#{elm_t}, #{@cvar})" ]
565
+ [ "#{retname} = GLib::List.wrap(#{elm_t}, #{cvar})" ]
756
566
  end
757
567
  end
758
568
 
759
569
  # Implements argument processing for GSList return values.
760
570
  class SListReturnValue < ReturnValue
571
+ include Argument::ListBase
572
+
761
573
  def post
762
- elm_t = subtype_tag.inspect
763
- [ "#{@retname} = GLib::SList.wrap(#{elm_t}, #{@cvar})" ]
574
+ [ "#{retname} = GLib::SList.wrap(#{elm_t}, #{cvar})" ]
764
575
  end
765
576
  end
766
577
 
767
578
  # Implements argument processing for GHashTable return values.
768
579
  class HashTableReturnValue < ReturnValue
580
+ include Argument::HashTableBase
581
+
769
582
  def post
770
- key_t = subtype_tag(0).inspect
771
- val_t = subtype_tag(1).inspect
772
- [ "#{@retname} = GLib::HashTable.wrap(#{key_t}, #{val_t}, #{@cvar})" ]
583
+ [ "#{retname} = GLib::HashTable.wrap(#{key_t}, #{val_t}, #{cvar})" ]
773
584
  end
774
585
  end
775
586
 
776
587
  # Implements argument processing for GHashTable return values.
777
588
  class ByteArrayReturnValue < ReturnValue
778
589
  def post
779
- [ "#{@retname} = GLib::ByteArray.wrap(#{@cvar})" ]
590
+ [ "#{retname} = GLib::ByteArray.wrap(#{cvar})" ]
780
591
  end
781
592
  end
782
593
 
783
594
  # Implements argument processing for GHashTable return values.
784
595
  class ArrayReturnValue < ReturnValue
596
+ include Argument::ListBase
597
+
785
598
  def post
786
- tag = subtype_tag
787
- etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
788
- [ "#{@retname} = GLib::Array.wrap(#{@cvar})",
789
- "#{@retname}.element_type = #{etype.inspect}" ]
599
+ [ "#{retname} = GLib::Array.wrap(#{cvar})",
600
+ "#{retname}.element_type = #{elm_t}" ]
790
601
  end
791
602
  end
792
603
 
@@ -797,7 +608,7 @@ module GirFFI::Builder
797
608
  @cvar
798
609
  else
799
610
  if type_tag == :utf8
800
- "#{@cvar}.force_encoding('utf-8')"
611
+ "#{cvar}.force_encoding('utf-8')"
801
612
  else
802
613
  @cvar
803
614
  end
@@ -808,22 +619,21 @@ module GirFFI::Builder
808
619
  # Implements argument processing for error handling arguments. These
809
620
  # arguments are not part of the introspected signature, but their
810
621
  # presence is indicated by the 'throws' attribute of the function.
811
- class ErrorArgument < Argument
812
- def prepare
813
- @callarg = @function_builder.new_var
622
+ class ErrorArgument < Argument::Base
623
+ def callarg
624
+ @callarg ||= @function_builder.new_var
814
625
  end
815
626
 
816
627
  def pre
817
- [ "#{@callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil" ]
628
+ [ "#{callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil" ]
818
629
  end
819
630
 
820
631
  def post
821
- [ "GirFFI::ArgHelper.check_error(#{@callarg})" ]
632
+ [ "GirFFI::ArgHelper.check_error(#{callarg})" ]
822
633
  end
823
634
  end
824
635
 
825
636
  # Argument builder that does nothing. Implements Null Object pattern.
826
- class NullArgument < Argument
827
- def prepare; end
637
+ class NullArgument < Argument::Base
828
638
  end
829
639
  end