gir_ffi 0.0.10 → 0.0.11

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.
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