gir_ffi 0.2.2 → 0.2.3

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 (69) hide show
  1. data/History.txt +6 -0
  2. data/lib/ffi-glib.rb +1 -0
  3. data/lib/ffi-glib/array.rb +49 -10
  4. data/lib/ffi-glib/hash_table.rb +19 -5
  5. data/lib/ffi-glib/list.rb +4 -1
  6. data/lib/ffi-glib/list_methods.rb +8 -1
  7. data/lib/ffi-glib/s_list.rb +4 -1
  8. data/lib/ffi-glib/strv.rb +31 -0
  9. data/lib/ffi-gobject.rb +2 -35
  10. data/lib/ffi-gobject/base.rb +38 -0
  11. data/lib/ffi-gobject/object.rb +28 -30
  12. data/lib/ffi-gobject/value.rb +72 -56
  13. data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -1
  14. data/lib/ffi-gobject_introspection/lib.rb +3 -1
  15. data/lib/gir_ffi/arg_helper.rb +2 -19
  16. data/lib/gir_ffi/builder/argument.rb +239 -305
  17. data/lib/gir_ffi/builder/argument/base.rb +12 -9
  18. data/lib/gir_ffi/builder/argument/in_base.rb +2 -6
  19. data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
  20. data/lib/gir_ffi/builder/argument/out_base.rb +0 -11
  21. data/lib/gir_ffi/builder/field.rb +55 -0
  22. data/lib/gir_ffi/builder/function.rb +7 -7
  23. data/lib/gir_ffi/builder/module.rb +5 -7
  24. data/lib/gir_ffi/builder/type/object.rb +0 -33
  25. data/lib/gir_ffi/builder/type/registered_type.rb +0 -16
  26. data/lib/gir_ffi/builder/type/struct_based.rb +3 -3
  27. data/lib/gir_ffi/builder/type/unintrospectable.rb +1 -1
  28. data/lib/gir_ffi/builder/type/with_layout.rb +26 -58
  29. data/lib/gir_ffi/builder/type/with_methods.rb +9 -11
  30. data/lib/gir_ffi/class_base.rb +24 -6
  31. data/lib/gir_ffi/ffi_ext/pointer.rb +15 -0
  32. data/lib/gir_ffi/in_pointer.rb +10 -5
  33. data/lib/gir_ffi/info_ext/i_field_info.rb +15 -0
  34. data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
  35. data/lib/gir_ffi/method_stubber.rb +18 -0
  36. data/lib/gir_ffi/type_map.rb +1 -0
  37. data/lib/gir_ffi/variable_name_generator.rb +2 -0
  38. data/lib/gir_ffi/version.rb +1 -1
  39. data/test/builder_test.rb +6 -5
  40. data/test/ffi-glib/array_test.rb +40 -5
  41. data/test/ffi-glib/hash_table_test.rb +27 -3
  42. data/test/ffi-glib/list_test.rb +23 -0
  43. data/test/ffi-glib/strv_test.rb +41 -0
  44. data/test/ffi-gobject/gobject_test.rb +26 -22
  45. data/test/ffi-gobject/value_test.rb +26 -1
  46. data/test/ffi-gobject_introspection/lib_test.rb +10 -0
  47. data/test/gir_ffi_test_helper.rb +1 -1
  48. data/test/integration/derived_classes_test.rb +31 -0
  49. data/test/integration/generated_gimarshallingtests_test.rb +29 -15
  50. data/test/integration/generated_gio_test.rb +5 -6
  51. data/test/integration/generated_regress_test.rb +11 -7
  52. data/test/integration/method_lookup_test.rb +32 -0
  53. data/test/interface_type_builder_test.rb +1 -1
  54. data/test/test_helper.rb +38 -0
  55. data/test/unit/argument_builder_test.rb +16 -4
  56. data/test/unit/class_base_test.rb +48 -0
  57. data/test/unit/function_builder_test.rb +144 -4
  58. data/test/unit/hash_table_element_type_provider_test.rb +16 -0
  59. data/test/unit/i_field_info_test.rb +39 -0
  60. data/test/unit/i_type_info_test.rb +23 -0
  61. data/test/unit/list_element_type_provider_test.rb +13 -0
  62. data/test/unit/module_builder_test.rb +1 -1
  63. data/test/unit/object_type_builder_test.rb +0 -17
  64. data/test/unit/struct_builder_test.rb +27 -39
  65. metadata +118 -60
  66. data/lib/gir_ffi/builder/argument/hash_table_base.rb +0 -20
  67. data/lib/gir_ffi/builder/argument/list_base.rb +0 -16
  68. data/test/class_base_test.rb +0 -10
  69. data/test/function_definition_builder_test.rb +0 -130
@@ -23,18 +23,28 @@ module GObjectIntrospection
23
23
  build_array_method :get_methods
24
24
 
25
25
  def find_method(name)
26
- @methods_hash ||= get_methods.inject({}) {|h,m| h[m.name] = m; h}
26
+ @methods_hash ||= make_method_hash
27
27
  @methods_hash[name]
28
28
  end
29
29
 
30
30
  def size
31
31
  Lib.g_struct_info_get_size @gobj
32
32
  end
33
+
33
34
  def alignment
34
35
  Lib.g_struct_info_get_alignment @gobj
35
36
  end
37
+
36
38
  def gtype_struct?
37
39
  Lib.g_struct_info_is_gtype_struct @gobj
38
40
  end
41
+
42
+ private
43
+
44
+ def make_method_hash
45
+ Hash.new.tap do |hash|
46
+ get_methods.each {|mth| hash[mth.name] = mth }
47
+ end
48
+ end
39
49
  end
40
50
  end
@@ -239,6 +239,8 @@ module GObjectIntrospection
239
239
  attach_function :g_interface_info_get_iface_struct, [:pointer], :pointer
240
240
 
241
241
  class GIArgument < FFI::Union
242
+ signed_size_t = "int#{FFI.type_size(:size_t) * 8}".to_sym
243
+
242
244
  layout :v_boolean, :int,
243
245
  :v_int8, :int8,
244
246
  :v_uint8, :uint8,
@@ -256,7 +258,7 @@ module GObjectIntrospection
256
258
  :v_uint, :uint,
257
259
  :v_long, :long,
258
260
  :v_ulong, :ulong,
259
- :v_ssize, :size_t, # FIXME: Needs to be signed.
261
+ :v_ssize, signed_size_t,
260
262
  :v_size, :size_t,
261
263
  :v_string, :string,
262
264
  :v_pointer, :pointer
@@ -90,25 +90,9 @@ module GirFFI
90
90
  alias_method :ptr_to_gtype_array, "ptr_to_#{type}_array"
91
91
  end
92
92
 
93
- def self.outptr_strv_to_utf8_array ptr
94
- strv_to_utf8_array ptr.read_pointer
95
- end
96
-
97
- # FIXME: Make GLib::Strv a class.
98
- def self.strv_to_utf8_array strv
99
- return [] if strv.null?
100
- arr, offset = [], 0
101
- until (ptr = strv.get_pointer offset).null? do
102
- arr << ptr.read_string
103
- offset += POINTER_SIZE
104
- end
105
- return arr
106
- end
107
-
108
93
  def self.check_error errpp
109
- errp = errpp.read_pointer
110
- # FIXME: Do not depend on GError from GObjectIntrospection namespace.
111
- raise GObjectIntrospection::GError.new(errp)[:message] unless errp.null?
94
+ err = GLib::Error.wrap(errpp.read_pointer)
95
+ raise err.message unless err.nil?
112
96
  end
113
97
 
114
98
  def self.check_fixed_array_size size, arr, name
@@ -121,7 +105,6 @@ module GirFFI
121
105
  AllocationHelper.safe_malloc FFI.type_size(type) * length
122
106
  end
123
107
 
124
- # FIXME: Quasi-circular dependency on generated module
125
108
  def self.object_pointer_to_object optr
126
109
  gtype = GObject.type_from_instance_pointer optr
127
110
  wrap_object_pointer_by_gtype optr, gtype
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  require 'gir_ffi/in_pointer'
2
4
  require 'gir_ffi/in_out_pointer'
3
5
 
@@ -5,8 +7,6 @@ require 'gir_ffi/builder/argument/base'
5
7
  require 'gir_ffi/builder/argument/in_base'
6
8
  require 'gir_ffi/builder/argument/out_base'
7
9
  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'
10
10
 
11
11
  module GirFFI::Builder
12
12
  module Argument
@@ -22,47 +22,61 @@ module GirFFI::Builder
22
22
  module InArgument
23
23
  def self.build var_gen, arginfo, libmodule
24
24
  type = arginfo.argument_type
25
- klass = builder_for type
26
- klass.new var_gen, arginfo.name, type, libmodule
27
- end
28
-
29
- def self.builder_for type
30
- case type.tag
31
- when :interface
32
- if type.interface.info_type == :callback
33
- CallbackInArgument
34
- else
35
- RegularInArgument
36
- end
37
- when :void
38
- VoidInArgument
39
- when :array
40
- if type.array_type == :c
41
- CArrayInArgument
42
- else
43
- RegularInArgument
44
- end
45
- when :glist
46
- ListInArgument
47
- when :gslist
48
- SListInArgument
49
- when :ghash
50
- HashTableInArgument
51
- when :utf8
52
- Utf8InArgument
53
- else
54
- RegularInArgument
55
- end
25
+ builder_for var_gen, arginfo.name, type, libmodule
26
+ end
27
+
28
+ def self.builder_for var_gen, name, type, libmodule
29
+ klass = case type.tag
30
+ when :interface
31
+ case type.interface.info_type
32
+ when :callback
33
+ return CallbackInArgument.new var_gen, name, type, libmodule
34
+ when :object, :struct
35
+ ObjectInArgument
36
+ else
37
+ RegularInArgument
38
+ end
39
+ when :void
40
+ VoidInArgument
41
+ when :array
42
+ if type.array_type == :c
43
+ CArrayInArgument
44
+ else
45
+ RegularInArgument
46
+ end
47
+ when :glist, :gslist
48
+ it = Argument::InBase.new var_gen, name, type
49
+ it.extend ContainerClassName
50
+ it.extend ListElementTypeProvider
51
+ it.extend WithTypedContainerPreMethod
52
+ return it
53
+ when :ghash
54
+ it = Argument::InBase.new var_gen, name, type
55
+ it.extend ContainerClassName
56
+ it.extend HashTableElementTypeProvider
57
+ it.extend WithTypedContainerPreMethod
58
+ return it
59
+ when :utf8
60
+ Utf8InArgument
61
+ else
62
+ RegularInArgument
63
+ end
64
+ return klass.new var_gen, name, type
56
65
  end
57
66
  end
58
67
 
59
68
  # Implements argument processing for callback arguments with direction
60
69
  # :in.
61
70
  class CallbackInArgument < Argument::InBase
71
+ def initialize var_gen, name, type, libmodule
72
+ super var_gen, name, type
73
+ @libmodule = libmodule
74
+ end
75
+
62
76
  def pre
63
77
  iface = type_info.interface
64
78
  [ "#{callarg} = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@name}",
65
- "::#{@libmodule}::CALLBACKS << #{callarg}" ]
79
+ "#{@libmodule}::CALLBACKS << #{callarg}" ]
66
80
  end
67
81
  end
68
82
 
@@ -74,38 +88,48 @@ module GirFFI::Builder
74
88
  end
75
89
  end
76
90
 
91
+ module ContainerClassName
92
+ TAG_TO_CONTAINER_CLASS_MAP = {
93
+ :glist => 'GLib::List',
94
+ :gslist => 'GLib::SList',
95
+ :ghash => 'GLib::HashTable',
96
+ :array => 'GLib::Array'
97
+ }
98
+
99
+ def class_name
100
+ TAG_TO_CONTAINER_CLASS_MAP[type_info.tag]
101
+ end
102
+ end
103
+
104
+ module ListElementTypeProvider
105
+ def elm_t
106
+ subtype_tag.inspect
107
+ end
108
+ end
109
+
110
+ module HashTableElementTypeProvider
111
+ def elm_t
112
+ [subtype_tag(0), subtype_tag(1)].inspect
113
+ end
114
+ end
115
+
77
116
  # Implements argument processing for array arguments with direction :in.
78
117
  class CArrayInArgument < Argument::InBase
118
+ include ListElementTypeProvider
79
119
  def pre
80
120
  pr = []
81
121
  size = type_info.array_fixed_size
82
122
  if size > -1
83
123
  pr << "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
84
124
  end
85
- pr << "#{callarg} = GirFFI::InPointer.from_array #{subtype_tag.inspect}, #{@name}"
125
+ pr << "#{callarg} = GirFFI::InPointer.from_array #{elm_t}, #{@name}"
86
126
  pr
87
127
  end
88
128
  end
89
129
 
90
- # Implements argument processing for glist arguments with
91
- # direction :in.
92
- class ListInArgument < Argument::InBase
93
- def pre
94
- [ "#{callarg} = GLib::List.from_array #{subtype_tag.inspect}, #{@name}" ]
95
- end
96
- end
97
-
98
- # Implements argument processing for gslist arguments with direction :in.
99
- class SListInArgument < Argument::InBase
100
- def pre
101
- [ "#{callarg} = GLib::SList.from_array #{subtype_tag.inspect}, #{@name}" ]
102
- end
103
- end
104
-
105
- # Implements argument processing for ghash arguments with direction :in.
106
- class HashTableInArgument < Argument::InBase
130
+ module WithTypedContainerPreMethod
107
131
  def pre
108
- [ "#{callarg} = GLib::HashTable.from_hash #{subtype_tag(0).inspect}, #{subtype_tag(1).inspect}, #{@name}" ]
132
+ [ "#{callarg} = #{class_name}.from #{elm_t}, #{@name}" ]
109
133
  end
110
134
  end
111
135
 
@@ -117,6 +141,14 @@ module GirFFI::Builder
117
141
  end
118
142
  end
119
143
 
144
+ # Implements argument processing for arguments with direction :in that
145
+ # are GObjects.
146
+ class ObjectInArgument < Argument::InBase
147
+ def pre
148
+ [ "#{callarg} = #{argument_class_name}.from #{@name}" ]
149
+ end
150
+ end
151
+
120
152
  # Implements argument processing for arguments with direction :in whose
121
153
  # type-specific processing is left to FFI (e.g., ints and floats, and
122
154
  # objects that implement to_ptr.).
@@ -156,47 +188,53 @@ module GirFFI::Builder
156
188
  when :c
157
189
  CArrayOutArgument
158
190
  when :array
159
- ArrayOutArgument
191
+ it = PointerLikeOutArgument.new var_gen, arginfo.name, type
192
+ it.extend ContainerClassName
193
+ it.extend ListElementTypeProvider
194
+ it.extend WithTypedContainerPostMethod
195
+ return it
160
196
  end
161
197
  end
162
- when :glist
163
- ListOutArgument
164
- when :gslist
165
- SListOutArgument
198
+ when :glist, :gslist
199
+ it = PointerLikeOutArgument.new var_gen, arginfo.name, type
200
+ it.extend ContainerClassName
201
+ it.extend ListElementTypeProvider
202
+ it.extend WithTypedContainerPostMethod
203
+ return it
166
204
  when :ghash
167
- HashTableOutArgument
205
+ it = PointerLikeOutArgument.new var_gen, arginfo.name, type
206
+ it.extend ContainerClassName
207
+ it.extend HashTableElementTypeProvider
208
+ it.extend WithTypedContainerPostMethod
209
+ return it
168
210
  else
169
211
  RegularOutArgument
170
212
  end
171
- klass.new var_gen, arginfo.name, type, libmodule
213
+ klass.new var_gen, arginfo.name, type
172
214
  end
173
215
  end
174
216
 
175
217
  # Implements argument processing for arguments with direction
176
218
  # :out that are neither arrays nor 'interfaces'.
177
219
  class RegularOutArgument < Argument::OutBase
178
- def post
179
- [ "#{retname} = #{callarg}.to_value" ]
220
+ def pre
221
+ [ "#{callarg} = GirFFI::InOutPointer.for #{type_tag.inspect}" ]
180
222
  end
181
223
 
182
- private
183
-
184
- def base_type
185
- type_tag
224
+ def post
225
+ [ "#{retname} = #{callarg}.to_value" ]
186
226
  end
187
227
  end
188
228
 
189
229
  # Implements argument processing for arguments with direction
190
230
  # :out that are enums
191
- class EnumOutArgument < RegularOutArgument
192
- def post
193
- [ "#{retname} = #{argument_class_name}[#{callarg}.to_value]" ]
231
+ class EnumOutArgument < Argument::OutBase
232
+ def pre
233
+ [ "#{callarg} = GirFFI::InOutPointer.for :gint32" ]
194
234
  end
195
235
 
196
- private
197
-
198
- def base_type
199
- :gint32
236
+ def post
237
+ [ "#{retname} = #{argument_class_name}[#{callarg}.to_value]" ]
200
238
  end
201
239
  end
202
240
 
@@ -212,32 +250,9 @@ module GirFFI::Builder
212
250
  end
213
251
  end
214
252
 
215
- # Implements argument processing for interface arguments with direction
216
- # :out (structs, objects, etc.).
217
- class InterfaceOutArgument < Argument::OutBase
218
- def pre
219
- [ "#{callarg} = GirFFI::InOutPointer.for :pointer" ]
220
- end
221
-
222
- def post
223
- [ "#{retname} = #{argument_class_name}.wrap #{callarg}.to_value" ]
224
- end
225
- end
226
-
227
- # Base class for arguments with direction :out for which the base type is
228
- # a pointer: For these, a pointer to a pointer needs to be passed to the
229
- # C function.
230
- class PointerLikeOutArgument < Argument::OutBase
231
- private
232
-
233
- def base_type
234
- :pointer
235
- end
236
- end
237
-
238
253
  # Implements argument processing for array arguments with direction
239
254
  # :out.
240
- class CArrayOutArgument < PointerLikeOutArgument
255
+ class CArrayOutArgument < Argument::OutBase
241
256
  def pre
242
257
  [ "#{callarg} = GirFFI::InOutPointer.for_array #{subtype_tag_or_class_name}" ]
243
258
  end
@@ -247,54 +262,34 @@ module GirFFI::Builder
247
262
  end
248
263
  end
249
264
 
250
- # Implements argument processing for strv arguments with direction
251
- # :out.
252
- class StrvOutArgument < PointerLikeOutArgument
253
- def post
254
- [ "#{retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{callarg}" ]
255
- end
256
- end
257
-
258
- # Implements argument processing for GArray arguments with direction
259
- # :out.
260
- class ArrayOutArgument < PointerLikeOutArgument
261
- include Argument::ListBase
262
-
263
- def post
264
- pp = []
265
- pp << "#{retname} = GLib::Array.wrap #{callarg}.to_value"
266
- pp << "#{retname}.element_type = #{elm_t}"
267
- pp
265
+ # Base class for arguments with direction :out for which the base type is
266
+ # a pointer: For these, a pointer to a pointer needs to be passed to the
267
+ # C function.
268
+ class PointerLikeOutArgument < Argument::OutBase
269
+ def pre
270
+ [ "#{callarg} = GirFFI::InOutPointer.for :pointer" ]
268
271
  end
269
272
  end
270
273
 
271
- # Implements argument processing for glist arguments with direction
272
- # :out.
273
- class ListOutArgument < PointerLikeOutArgument
274
- include Argument::ListBase
275
-
274
+ # Implements argument processing for interface arguments with direction
275
+ # :out (structs, objects, etc.).
276
+ class InterfaceOutArgument < PointerLikeOutArgument
276
277
  def post
277
- [ "#{retname} = GLib::List.wrap #{elm_t}, #{callarg}.to_value" ]
278
+ [ "#{retname} = #{argument_class_name}.wrap #{callarg}.to_value" ]
278
279
  end
279
280
  end
280
281
 
281
- # Implements argument processing for gslist arguments with direction
282
+ # Implements argument processing for strv arguments with direction
282
283
  # :out.
283
- class SListOutArgument < PointerLikeOutArgument
284
- include Argument::ListBase
285
-
284
+ class StrvOutArgument < PointerLikeOutArgument
286
285
  def post
287
- [ "#{retname} = GLib::SList.wrap #{elm_t}, #{callarg}.to_value" ]
286
+ [ "#{retname} = GLib::Strv.wrap #{callarg}.to_value" ]
288
287
  end
289
288
  end
290
289
 
291
- # Implements argument processing for ghash arguments with direction
292
- # :out.
293
- class HashTableOutArgument < PointerLikeOutArgument
294
- include Argument::HashTableBase
295
-
290
+ module WithTypedContainerPostMethod
296
291
  def post
297
- [ "#{retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, #{callarg}.to_value" ]
292
+ [ "#{retname} = #{class_name}.wrap #{elm_t}, #{callarg}.to_value" ]
298
293
  end
299
294
  end
300
295
 
@@ -318,20 +313,33 @@ module GirFFI::Builder
318
313
  when :c
319
314
  CArrayInOutArgument
320
315
  when :array
321
- ArrayInOutArgument
316
+ it = Argument::InOutBase.new var_gen, arginfo.name, type
317
+ it.extend ContainerClassName
318
+ it.extend ListElementTypeProvider
319
+ it.extend WithTypedContainerInOutPreMethod
320
+ it.extend WithTypedContainerPostMethod
321
+ return it
322
322
  end
323
323
  end
324
- when :glist
325
- ListInOutArgument
326
- when :gslist
327
- SListInOutArgument
324
+ when :glist, :gslist
325
+ it = Argument::InOutBase.new var_gen, arginfo.name, type
326
+ it.extend ContainerClassName
327
+ it.extend ListElementTypeProvider
328
+ it.extend WithTypedContainerInOutPreMethod
329
+ it.extend WithTypedContainerPostMethod
330
+ return it
328
331
  when :ghash
329
- HashTableInOutArgument
332
+ it = Argument::InOutBase.new var_gen, arginfo.name, type
333
+ it.extend ContainerClassName
334
+ it.extend HashTableElementTypeProvider
335
+ it.extend WithTypedContainerInOutPreMethod
336
+ it.extend WithTypedContainerPostMethod
337
+ return it
330
338
  else
331
339
  RegularInOutArgument
332
340
  end
333
341
 
334
- klass.new var_gen, arginfo.name, type, libmodule
342
+ klass.new var_gen, arginfo.name, type
335
343
  end
336
344
  end
337
345
 
@@ -353,7 +361,7 @@ module GirFFI::Builder
353
361
  # :inout (structs, objects, etc.).
354
362
  class InterfaceInOutArgument < Argument::InOutBase
355
363
  def pre
356
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{@name}.to_ptr" ]
364
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{argument_class_name}.from(#{@name}).to_ptr" ]
357
365
  end
358
366
 
359
367
  def post
@@ -364,20 +372,22 @@ module GirFFI::Builder
364
372
  # Implements argument processing for strv arguments with direction
365
373
  # :inout.
366
374
  class StrvInOutArgument < Argument::InOutBase
375
+ include ListElementTypeProvider
367
376
  def pre
368
- [ "#{callarg} = GirFFI::InOutPointer.from_array #{subtype_tag.inspect}, #{@name}" ]
377
+ [ "#{callarg} = GirFFI::InOutPointer.from_array #{elm_t}, #{@name}" ]
369
378
  end
370
379
 
371
380
  def post
372
- [ "#{retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{callarg}" ]
381
+ [ "#{retname} = GLib::Strv.wrap(#{callarg}.to_value)" ]
373
382
  end
374
383
  end
375
384
 
376
385
  # Implements argument processing for array arguments with direction
377
386
  # :inout.
378
387
  class CArrayInOutArgument < Argument::InOutBase
388
+ include ListElementTypeProvider
379
389
  def pre
380
- [ "#{callarg} = GirFFI::InOutPointer.from_array #{subtype_tag.inspect}, #{@name}" ]
390
+ [ "#{callarg} = GirFFI::InOutPointer.from_array #{elm_t}, #{@name}" ]
381
391
  end
382
392
 
383
393
  def postpost
@@ -385,65 +395,11 @@ module GirFFI::Builder
385
395
  pst = [ "#{retname} = #{callarg}.to_sized_array_value #{size}" ]
386
396
  pst
387
397
  end
388
-
389
398
  end
390
399
 
391
- # Implements argument processing for GArray arguments with direction
392
- # :inout.
393
- class ArrayInOutArgument < Argument::InOutBase
394
- include Argument::ListBase
395
-
400
+ module WithTypedContainerInOutPreMethod
396
401
  def pre
397
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{@name}" ]
398
- end
399
-
400
- def post
401
- pp = []
402
- pp << "#{retname} = GLib::Array.wrap(#{callarg}.to_value)"
403
- pp << "#{retname}.element_type = #{elm_t}"
404
- pp
405
- end
406
- end
407
-
408
- # Implements argument processing for glist arguments with direction
409
- # :inout.
410
- class ListInOutArgument < Argument::InOutBase
411
- include Argument::ListBase
412
-
413
- def pre
414
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GLib::List.from_array(#{subtype_tag.inspect}, #{@name})" ]
415
- end
416
-
417
- def post
418
- [ "#{retname} = GLib::List.wrap #{elm_t}, #{callarg}.to_value" ]
419
- end
420
- end
421
-
422
- # Implements argument processing for gslist arguments with direction
423
- # :inout.
424
- class SListInOutArgument < Argument::InOutBase
425
- include Argument::ListBase
426
-
427
- def pre
428
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GLib::SList.from_array(#{subtype_tag.inspect}, #{@name})" ]
429
- end
430
-
431
- def post
432
- [ "#{retname} = GLib::SList.wrap #{elm_t}, #{callarg}.to_value" ]
433
- end
434
- end
435
-
436
- # Implements argument processing for ghash arguments with direction
437
- # :inout.
438
- class HashTableInOutArgument < Argument::InOutBase
439
- include Argument::HashTableBase
440
-
441
- def pre
442
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, GLib::HashTable.from_hash(#{key_t}, #{val_t}, #{@name})" ]
443
- end
444
-
445
- def post
446
- [ "#{retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, #{callarg}.to_value" ]
402
+ [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{class_name}.from(#{elm_t}, #{@name})" ]
447
403
  end
448
404
  end
449
405
 
@@ -464,76 +420,91 @@ module GirFFI::Builder
464
420
  end
465
421
  end
466
422
 
467
- # Implements argument processing for return values.
468
- class ReturnValue < Argument::Base
469
- def cvar
470
- @cvar ||= @var_gen.new_var
471
- end
472
-
473
- def retname
474
- @retname ||= @var_gen.new_var
475
- end
476
-
423
+ module ReturnValueFactory
477
424
  def self.build var_gen, arginfo
478
- type = arginfo.return_type
479
- klass = builder_for(type, arginfo.constructor?)
480
- klass.new var_gen, arginfo.name, type, nil
425
+ builder_for(var_gen,
426
+ arginfo.name,
427
+ arginfo.return_type,
428
+ arginfo.constructor?)
481
429
  end
482
430
 
483
- def self.builder_for type, is_constructor
431
+ def self.builder_for var_gen, name, type, is_constructor
484
432
  if type.tag == :interface and
485
433
  [:interface, :object].include? type.interface.info_type
486
- if is_constructor
487
- ConstructorReturnValue
488
- else
489
- ObjectReturnValue
490
- end
434
+ klass = if is_constructor
435
+ ConstructorReturnValue
436
+ else
437
+ ObjectReturnValue
438
+ end
439
+ klass.new var_gen, name, type
491
440
  else
492
- builder_for_field_getter type
441
+ builder_for_field_getter var_gen, name, type
493
442
  end
494
443
  end
495
444
 
496
- def self.builder_for_field_getter type
497
- case type.tag
498
- when :void
499
- if type.pointer?
500
- RegularReturnValue
501
- else
502
- VoidReturnValue
503
- end
504
- when :interface
505
- case type.interface.info_type
506
- when :struct, :union, :interface, :object
507
- InterfaceReturnValue
508
- else
509
- RegularReturnValue
510
- end
511
- when :array
512
- if type.zero_terminated?
513
- StrvReturnValue
514
- else
515
- case type.array_type
516
- when :c
517
- CArrayReturnValue
518
- when :array
519
- ArrayReturnValue
520
- when :byte_array
521
- ByteArrayReturnValue
522
- else
523
- PtrArrayReturnValue
524
- end
525
- end
526
- when :glist
527
- ListReturnValue
528
- when :gslist
529
- SListReturnValue
530
- when :ghash
531
- HashTableReturnValue
532
- when :utf8
533
- Utf8ReturnValue
534
- else
535
- RegularReturnValue
536
- end
445
+ def self.builder_for_field_getter var_gen, name, type
446
+ klass = case type.tag
447
+ when :void
448
+ if type.pointer?
449
+ RegularReturnValue
450
+ else
451
+ VoidReturnValue
452
+ end
453
+ when :interface
454
+ case type.interface.info_type
455
+ when :struct, :union, :interface, :object
456
+ InterfaceReturnValue
457
+ else
458
+ RegularReturnValue
459
+ end
460
+ when :array
461
+ if type.zero_terminated?
462
+ StrvReturnValue
463
+ else
464
+ case type.array_type
465
+ when :c
466
+ CArrayReturnValue
467
+ when :array
468
+ it = ReturnValue.new var_gen, name, type
469
+ it.extend ContainerClassName
470
+ it.extend ListElementTypeProvider
471
+ it.extend WithTypedContainerPostMethod
472
+ return it
473
+ when :byte_array
474
+ ByteArrayReturnValue
475
+ else
476
+ PtrArrayReturnValue
477
+ end
478
+ end
479
+ when :glist, :gslist
480
+ it = ReturnValue.new var_gen, name, type
481
+ it.extend ContainerClassName
482
+ it.extend ListElementTypeProvider
483
+ it.extend WithTypedContainerPostMethod
484
+ return it
485
+ when :ghash
486
+ it = ReturnValue.new var_gen, name, type
487
+ it.extend ContainerClassName
488
+ it.extend HashTableElementTypeProvider
489
+ it.extend WithTypedContainerPostMethod
490
+ return it
491
+ when :utf8
492
+ Utf8ReturnValue
493
+ else
494
+ RegularReturnValue
495
+ end
496
+ klass.new var_gen, name, type
497
+ end
498
+ end
499
+
500
+ # Implements argument processing for return values.
501
+ class ReturnValue < Argument::Base
502
+ def cvar
503
+ callarg
504
+ end
505
+
506
+ def retname
507
+ @retname ||= @var_gen.new_var
537
508
  end
538
509
 
539
510
  def inarg
@@ -582,41 +553,14 @@ module GirFFI::Builder
582
553
  # Implements argument processing for NULL-terminated string array return values.
583
554
  class StrvReturnValue < ReturnValue
584
555
  def post
585
- [ "#{retname} = GirFFI::ArgHelper.strv_to_utf8_array #{cvar}" ]
556
+ [ "#{retname} = GLib::Strv.wrap(#{cvar})" ]
586
557
  end
587
558
  end
588
559
 
589
560
  # Implements argument processing for UTF8 string return values.
590
561
  class Utf8ReturnValue < ReturnValue
591
562
  def post
592
- [ "#{retname} = GirFFI::ArgHelper.ptr_to_utf8 #{@cvar}" ]
593
- end
594
- end
595
-
596
- # Implements argument processing for GList return values.
597
- class ListReturnValue < ReturnValue
598
- include Argument::ListBase
599
-
600
- def post
601
- [ "#{retname} = GLib::List.wrap(#{elm_t}, #{cvar})" ]
602
- end
603
- end
604
-
605
- # Implements argument processing for GSList return values.
606
- class SListReturnValue < ReturnValue
607
- include Argument::ListBase
608
-
609
- def post
610
- [ "#{retname} = GLib::SList.wrap(#{elm_t}, #{cvar})" ]
611
- end
612
- end
613
-
614
- # Implements argument processing for GHashTable return values.
615
- class HashTableReturnValue < ReturnValue
616
- include Argument::HashTableBase
617
-
618
- def post
619
- [ "#{retname} = GLib::HashTable.wrap(#{key_t}, #{val_t}, #{cvar})" ]
563
+ [ "#{retname} = GirFFI::ArgHelper.ptr_to_utf8 #{cvar}" ]
620
564
  end
621
565
  end
622
566
 
@@ -627,16 +571,6 @@ module GirFFI::Builder
627
571
  end
628
572
  end
629
573
 
630
- # Implements argument processing for GArray return values.
631
- class ArrayReturnValue < ReturnValue
632
- include Argument::ListBase
633
-
634
- def post
635
- [ "#{retname} = GLib::Array.wrap(#{cvar})",
636
- "#{retname}.element_type = #{elm_t}" ]
637
- end
638
- end
639
-
640
574
  # Implements argument processing for GPtrArray return values.
641
575
  class PtrArrayReturnValue < ReturnValue
642
576
  def post
@@ -647,7 +581,7 @@ module GirFFI::Builder
647
581
  # Implements argument processing for other return values.
648
582
  class RegularReturnValue < ReturnValue
649
583
  def retval
650
- @cvar
584
+ @callarg
651
585
  end
652
586
  end
653
587
 
@@ -655,10 +589,6 @@ module GirFFI::Builder
655
589
  # arguments are not part of the introspected signature, but their
656
590
  # presence is indicated by the 'throws' attribute of the function.
657
591
  class ErrorArgument < Argument::Base
658
- def callarg
659
- @callarg ||= @var_gen.new_var
660
- end
661
-
662
592
  def pre
663
593
  [ "#{callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil" ]
664
594
  end
@@ -669,6 +599,10 @@ module GirFFI::Builder
669
599
  end
670
600
 
671
601
  # Argument builder that does nothing. Implements Null Object pattern.
672
- class NullArgument < Argument::Base
602
+ class NullArgument
603
+ def initialize *args; end
604
+ def pre; []; end
605
+ def post; []; end
606
+ def callarg; end
673
607
  end
674
608
  end