gir_ffi 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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