gir_ffi 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.4.3 / 2012-11-02
2
+
3
+ * Remove gobject-introspection version check
4
+ * Make tests pass with gobject-introspection 1.34
5
+ * Ongoing refactoring
6
+
1
7
  == 0.4.2 / 2012-09-22
2
8
 
3
9
  * Make objects and interfaces wrap poiners in the class that matches
@@ -0,0 +1,22 @@
1
+ module GLib
2
+ # Extra methods for GLib::Strv.
3
+ class Strv
4
+ def self.from it
5
+ case it
6
+ when nil
7
+ nil
8
+ when FFI::Pointer
9
+ wrap it
10
+ when self
11
+ it
12
+ else
13
+ from_enumerable it
14
+ end
15
+ end
16
+
17
+ def self.from_enumerable enum
18
+ self.wrap GirFFI::InPointer.from_array :utf8, enum
19
+ end
20
+ end
21
+ end
22
+
data/lib/ffi-glib.rb CHANGED
@@ -9,6 +9,7 @@ require 'ffi-glib/hash_table'
9
9
  require 'ffi-glib/byte_array'
10
10
  require 'ffi-glib/array'
11
11
  require 'ffi-glib/ptr_array'
12
+ require 'ffi-glib/strv'
12
13
 
13
14
  module GLib
14
15
  # @deprecated Compatibility function. Remove in version 0.5.0.
@@ -2,7 +2,14 @@ module GObjectIntrospection
2
2
  # Wraps a GIConstantInfo struct; represents an constant.
3
3
  class IConstantInfo < IBaseInfo
4
4
  TYPE_TAG_TO_UNION_MEMBER = {
5
+ :gint8 => :v_int8,
6
+ :gint16 => :v_int16,
5
7
  :gint32 => :v_int32,
8
+ :gint64 => :v_int64,
9
+ :guint8 => :v_uint8,
10
+ :guint16 => :v_uint16,
11
+ :guint32 => :v_uint32,
12
+ :guint64 => :v_uint64,
6
13
  :gdouble => :v_double,
7
14
  :utf8 => :v_string
8
15
  }
@@ -3,19 +3,7 @@ require 'ffi'
3
3
  module GObjectIntrospection
4
4
  module Lib
5
5
  extend FFI::Library
6
- begin
7
- ffi_lib "girepository-1.0.so.1"
8
- rescue LoadError
9
- begin
10
- ffi_lib "girepository-1.0.so.0"
11
- warn "This old version of gobject-introspection is not supported by GirFFI."
12
- warn "Please upgrade to at least version 0.10.0."
13
- rescue LoadError
14
- ffi_lib "girepository-1.0"
15
- warn "This platform and/or version of gobject-introspection are not supported by GirFFI."
16
- warn "Please file bugs for any errors found."
17
- end
18
- end
6
+ ffi_lib "girepository-1.0"
19
7
 
20
8
  # IRepository
21
9
  enum :IRepositoryLoadFlags, [:LAZY, (1<<0)]
@@ -1,3 +1,5 @@
1
+ require 'gir_ffi/info_ext/i_registered_type_info'
2
+
1
3
  module GirFFI
2
4
  module Builder
3
5
  module Argument
@@ -17,7 +19,7 @@ module GirFFI
17
19
 
18
20
  attr_accessor :length_arg, :array_arg
19
21
 
20
- def initialize var_gen, name, typeinfo
22
+ def initialize var_gen, name, typeinfo, direction
21
23
  @typeinfo = typeinfo
22
24
  @inarg = nil
23
25
  @retname = nil
@@ -35,6 +37,14 @@ module GirFFI
35
37
  type_info.tag
36
38
  end
37
39
 
40
+ def specialized_type_tag
41
+ type_info.flattened_tag
42
+ end
43
+
44
+ def type_specification
45
+ type_info.type_specification
46
+ end
47
+
38
48
  TAG_TO_WRAPPER_CLASS_MAP = {
39
49
  :glist => 'GLib::List',
40
50
  :gslist => 'GLib::SList',
@@ -47,14 +57,25 @@ module GirFFI
47
57
  def argument_class_name
48
58
  case (tag = type_tag)
49
59
  when :interface
50
- iface = type_info.interface
51
- # FIXME: Extract to ITypeInfo.
52
- "::#{iface.safe_namespace}::#{iface.name}"
60
+ type_info.interface_type_name
53
61
  when :array
54
- if type_info.zero_terminated?
55
- 'GLib::Strv'
56
- else
62
+ case type_info.array_type
63
+ when :byte_array
64
+ 'GLib::ByteArray'
65
+ when :array
57
66
  'GLib::Array'
67
+ when :ptr_array
68
+ 'GLib::PtrArray'
69
+ else # :c
70
+ if type_info.zero_terminated?
71
+ if type_info.element_type == :utf8
72
+ 'GLib::Strv'
73
+ else
74
+ 'GirFFI::InPointer'
75
+ end
76
+ else
77
+ 'GirFFI::InPointer'
78
+ end
58
79
  end
59
80
  else
60
81
  TAG_TO_WRAPPER_CLASS_MAP[tag]
@@ -65,8 +86,7 @@ module GirFFI
65
86
  type = type_info.param_type(index)
66
87
  tag = type.tag
67
88
  base = if tag == :interface
68
- iface = type.interface
69
- "::#{iface.safe_namespace}::#{iface.name}"
89
+ type.interface_type_name
70
90
  else
71
91
  tag.inspect
72
92
  end
@@ -4,12 +4,11 @@ module GirFFI
4
4
  # Abstract base class implementing argument processing for arguments
5
5
  # with direction :in.
6
6
  class InBase < Base
7
- def initialize var_gen, name, typeinfo
8
- super var_gen, name, typeinfo
7
+ def initialize var_gen, name, typeinfo, direction
8
+ super var_gen, name, typeinfo, direction
9
9
  @inarg = @name
10
10
  end
11
11
  end
12
12
  end
13
13
  end
14
14
  end
15
-
@@ -4,8 +4,8 @@ module GirFFI
4
4
  # Abstract base class implementing argument processing for arguments
5
5
  # with direction :inout.
6
6
  class InOutBase < Base
7
- def initialize var_gen, name, typeinfo
8
- super var_gen, name, typeinfo
7
+ def initialize var_gen, name, typeinfo, direction
8
+ super var_gen, name, typeinfo, direction
9
9
  @inarg = @name
10
10
  end
11
11
 
@@ -16,6 +16,3 @@ module GirFFI
16
16
  end
17
17
  end
18
18
  end
19
-
20
-
21
-
@@ -22,28 +22,22 @@ module GirFFI::Builder
22
22
  module InArgument
23
23
  def self.build var_gen, arginfo, libmodule
24
24
  type = arginfo.argument_type
25
- builder_for var_gen, arginfo.name, type, libmodule
25
+ builder_for var_gen, arginfo.name, type, arginfo.direction, libmodule
26
26
  end
27
27
 
28
- def self.builder_for var_gen, name, type, libmodule
28
+ def self.builder_for var_gen, name, type, direction, libmodule
29
29
  klass = case type.tag
30
30
  when :interface
31
31
  case type.interface.info_type
32
32
  when :callback
33
33
  return CallbackInArgument.new var_gen, name, type, libmodule
34
34
  else
35
- RegularInArgument
36
- end
37
- when :array
38
- if type.array_type == :c
39
- CArrayInArgument
40
- else
41
- RegularInArgument
35
+ RegularArgument
42
36
  end
43
37
  else
44
- RegularInArgument
38
+ RegularArgument
45
39
  end
46
- return klass.new var_gen, name, type
40
+ return klass.new var_gen, name, type, direction
47
41
  end
48
42
  end
49
43
 
@@ -51,7 +45,7 @@ module GirFFI::Builder
51
45
  # :in.
52
46
  class CallbackInArgument < Argument::InBase
53
47
  def initialize var_gen, name, type, libmodule
54
- super var_gen, name, type
48
+ super var_gen, name, type, :in
55
49
  @libmodule = libmodule
56
50
  end
57
51
 
@@ -62,19 +56,6 @@ module GirFFI::Builder
62
56
  end
63
57
  end
64
58
 
65
- # Implements argument processing for array arguments with direction :in.
66
- class CArrayInArgument < Argument::InBase
67
- def pre
68
- pr = []
69
- size = type_info.array_fixed_size
70
- if size > -1
71
- pr << "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
72
- end
73
- pr << "#{callarg} = GirFFI::InPointer.from_array #{elm_t}, #{@name}"
74
- pr
75
- end
76
- end
77
-
78
59
  # Implements argument processing for arguments with direction :in whose
79
60
  # type-specific processing is left to FFI (e.g., ints and floats, and
80
61
  # objects that implement to_ptr.).
@@ -87,38 +68,160 @@ module GirFFI::Builder
87
68
  #
88
69
  # Implements argument processing for void pointer arguments with
89
70
  # direction :in.
90
- class RegularInArgument < Argument::InBase
71
+ #
72
+ # Implements argument processing for interface arguments with direction
73
+ # :inout (structs, objects, etc.).
74
+ #
75
+ # Implements argument processing for arguments with direction
76
+ # :out that are neither arrays nor 'interfaces'.
77
+ class RegularArgument < Argument::Base
78
+ def initialize var_gen, name, typeinfo, direction
79
+ super var_gen, name, typeinfo, direction
80
+ @direction = direction
81
+ end
82
+
83
+ def inarg
84
+ if has_input_value?
85
+ @array_arg.nil? ? @name : nil
86
+ end
87
+ end
88
+
89
+ def retname
90
+ if has_output_value?
91
+ @retname ||= @var_gen.new_var
92
+ end
93
+ end
94
+
91
95
  def pre
92
96
  pr = []
93
- assign_array_length(pr)
94
- set_function_call_argument(pr)
97
+ if has_input_value?
98
+ pr << fixed_array_size_check if needs_size_check?
99
+ pr << array_length_assignment if is_array_length_parameter?
100
+ end
101
+ pr << set_function_call_argument
95
102
  pr
96
103
  end
97
104
 
98
- def assign_array_length(pr)
99
- if @array_arg
100
- arrname = @array_arg.name
101
- pr << "#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length"
105
+ def post
106
+ result = []
107
+ if has_output_value?
108
+ value = case @direction
109
+ when :inout
110
+ "#{argument_class_name}.wrap(#{output_conversion_arguments})"
111
+ when :out
112
+ "#{callarg}.to_value"
113
+ end
114
+ result << "#{retname} = #{value}"
115
+ end
116
+ result
117
+ end
118
+
119
+ private
120
+
121
+ def is_array_length_parameter?
122
+ @array_arg
123
+ end
124
+
125
+ def needs_size_check?
126
+ if type_tag == :array
127
+ size = type_info.array_fixed_size
128
+ if size > -1
129
+ true
130
+ end
102
131
  end
103
132
  end
104
133
 
105
- def set_function_call_argument(pr)
106
- if type_tag == :interface && [:object, :struct].include?(type_info.interface.info_type)
107
- pr << "#{callarg} = #{argument_class_name}.from #{@name}"
108
- elsif [:utf8, :void].include? type_tag
109
- pr << "#{callarg} = #{argument_class_name}.from #{type_tag.inspect}, #{@name}"
110
- elsif [:glist, :gslist, :ghash].include? type_tag
111
- pr << "#{callarg} = #{argument_class_name}.from #{elm_t}, #{@name}"
134
+ def fixed_array_size_check
135
+ size = type_info.array_fixed_size
136
+ "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
137
+ end
138
+
139
+ def has_output_value?
140
+ @direction == :inout || @direction == :out
141
+ end
142
+
143
+ def has_input_value?
144
+ @direction == :inout || @direction == :in
145
+ end
146
+
147
+ def array_length_assignment
148
+ arrname = @array_arg.name
149
+ "#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length"
150
+ end
151
+
152
+ def set_function_call_argument
153
+ value = if @direction == :out
154
+ "GirFFI::InOutPointer.for #{type_tag.inspect}"
155
+ else
156
+ if needs_ingoing_parameter_conversion?
157
+ parameter_conversion
158
+ else
159
+ @name
160
+ end
161
+ end
162
+ "#{callarg} = #{value}"
163
+ end
164
+
165
+ def needs_outgoing_parameter_conversion?
166
+ case specialized_type_tag
167
+ when :object, :struct, :utf8, :void, :glist, :gslist, :ghash, :array, :c, :strv
168
+ true
169
+ else
170
+ false
171
+ end
172
+ end
173
+
174
+ def needs_ingoing_parameter_conversion?
175
+ case specialized_type_tag
176
+ when :object, :struct, :utf8, :void, :glist, :gslist, :ghash, :array, :c, :strv
177
+ true
178
+ else
179
+ false
180
+ end
181
+ end
182
+
183
+ def parameter_conversion
184
+ base = "#{argument_class_name}.from(#{parameter_conversion_arguments})"
185
+ if has_output_value?
186
+ "GirFFI::InOutPointer.from :pointer, #{base}"
112
187
  else
113
- pr << "#{callarg} = #{@name}"
188
+ base
114
189
  end
115
190
  end
191
+
192
+ def output_conversion_arguments
193
+ conversion_arguments "#{callarg}.to_value"
194
+ end
195
+
196
+ def parameter_conversion_arguments
197
+ conversion_arguments @name
198
+ end
199
+
200
+ def conversion_arguments name
201
+ case specialized_type_tag
202
+ when :utf8, :void
203
+ "#{self_t}, #{name}"
204
+ when :glist, :gslist, :ghash, :array
205
+ "#{elm_t}, #{name}"
206
+ when :c
207
+ "#{type_specification}, #{name}"
208
+ when :strv
209
+ "#{name}"
210
+ else
211
+ "#{name}"
212
+ end
213
+ end
214
+
215
+ def self_t
216
+ type_tag.inspect
217
+ end
116
218
  end
117
219
 
118
220
  # Implements argument processing for arguments with direction :out.
119
221
  module OutArgument
120
222
  def self.build var_gen, arginfo, libmodule
121
223
  type = arginfo.argument_type
224
+ direction = arginfo.direction
122
225
  klass = case type.tag
123
226
  when :interface
124
227
  case type.interface.info_type
@@ -139,35 +242,19 @@ module GirFFI::Builder
139
242
  when :c
140
243
  CArrayOutArgument
141
244
  when :array
142
- it = PointerLikeOutArgument.new var_gen, arginfo.name, type
245
+ it = PointerLikeOutArgument.new var_gen, arginfo.name, type, direction
143
246
  it.extend WithTypedContainerPostMethod
144
247
  return it
145
248
  end
146
249
  end
147
- when :glist, :gslist
148
- it = PointerLikeOutArgument.new var_gen, arginfo.name, type
149
- it.extend WithTypedContainerPostMethod
150
- return it
151
- when :ghash
152
- it = PointerLikeOutArgument.new var_gen, arginfo.name, type
250
+ when :glist, :gslist, :ghash
251
+ it = PointerLikeOutArgument.new var_gen, arginfo.name, type, direction
153
252
  it.extend WithTypedContainerPostMethod
154
253
  return it
155
254
  else
156
- RegularOutArgument
255
+ RegularArgument
157
256
  end
158
- klass.new var_gen, arginfo.name, type
159
- end
160
- end
161
-
162
- # Implements argument processing for arguments with direction
163
- # :out that are neither arrays nor 'interfaces'.
164
- class RegularOutArgument < Argument::OutBase
165
- def pre
166
- [ "#{callarg} = GirFFI::InOutPointer.for #{type_tag.inspect}" ]
167
- end
168
-
169
- def post
170
- [ "#{retname} = #{callarg}.to_value" ]
257
+ klass.new var_gen, arginfo.name, type, direction
171
258
  end
172
259
  end
173
260
 
@@ -237,13 +324,14 @@ module GirFFI::Builder
237
324
  module InOutArgument
238
325
  def self.build var_gen, arginfo, libmodule
239
326
  type = arginfo.argument_type
327
+ direction = arginfo.direction
240
328
  klass = case type.tag
241
329
  when :interface
242
330
  case type.interface.info_type
243
331
  when :enum, :flags
244
332
  EnumInOutArgument
245
333
  else
246
- InterfaceInOutArgument
334
+ RegularArgument
247
335
  end
248
336
  when :array
249
337
  if type.zero_terminated?
@@ -253,27 +341,16 @@ module GirFFI::Builder
253
341
  when :c
254
342
  CArrayInOutArgument
255
343
  when :array
256
- it = Argument::InOutBase.new var_gen, arginfo.name, type
257
- it.extend WithTypedContainerInOutPreMethod
258
- it.extend WithTypedContainerPostMethod
259
- return it
344
+ RegularArgument
260
345
  end
261
346
  end
262
- when :glist, :gslist
263
- it = Argument::InOutBase.new var_gen, arginfo.name, type
264
- it.extend WithTypedContainerInOutPreMethod
265
- it.extend WithTypedContainerPostMethod
266
- return it
267
- when :ghash
268
- it = Argument::InOutBase.new var_gen, arginfo.name, type
269
- it.extend WithTypedContainerInOutPreMethod
270
- it.extend WithTypedContainerPostMethod
271
- return it
347
+ when :glist, :gslist, :ghash
348
+ RegularArgument
272
349
  else
273
350
  RegularInOutArgument
274
351
  end
275
352
 
276
- klass.new var_gen, arginfo.name, type
353
+ klass.new var_gen, arginfo.name, type, direction
277
354
  end
278
355
  end
279
356
 
@@ -291,23 +368,11 @@ module GirFFI::Builder
291
368
  end
292
369
  end
293
370
 
294
- # Implements argument processing for interface arguments with direction
295
- # :inout (structs, objects, etc.).
296
- class InterfaceInOutArgument < Argument::InOutBase
297
- def pre
298
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{argument_class_name}.from(#{@name}).to_ptr" ]
299
- end
300
-
301
- def post
302
- [ "#{retname} = #{argument_class_name}.wrap(#{callarg}.to_value)" ]
303
- end
304
- end
305
-
306
371
  # Implements argument processing for strv arguments with direction
307
372
  # :inout.
308
373
  class StrvInOutArgument < Argument::InOutBase
309
374
  def pre
310
- [ "#{callarg} = GirFFI::InOutPointer.from_array #{elm_t}, #{@name}" ]
375
+ [ "#{callarg} = GirFFI::InOutPointer.from #{type_specification}, #{@name}" ]
311
376
  end
312
377
 
313
378
  def post
@@ -329,12 +394,6 @@ module GirFFI::Builder
329
394
  end
330
395
  end
331
396
 
332
- module WithTypedContainerInOutPreMethod
333
- def pre
334
- [ "#{callarg} = GirFFI::InOutPointer.from :pointer, #{argument_class_name}.from(#{elm_t}, #{@name})" ]
335
- end
336
- end
337
-
338
397
  # Implements argument processing for arguments with direction
339
398
  # :inout that are neither arrays nor 'interfaces'.
340
399
  class RegularInOutArgument < Argument::InOutBase
@@ -357,24 +416,25 @@ module GirFFI::Builder
357
416
  builder_for(var_gen,
358
417
  arginfo.name,
359
418
  arginfo.return_type,
419
+ :return,
360
420
  arginfo.constructor?)
361
421
  end
362
422
 
363
- def self.builder_for var_gen, name, type, is_constructor
423
+ def self.builder_for var_gen, name, type, direction, is_constructor
364
424
  if type.tag == :interface and
365
425
  [:interface, :object].include? type.interface.info_type
366
426
  klass = if is_constructor
367
427
  ConstructorReturnValue
368
428
  else
369
- ObjectReturnValue
429
+ WrappingReturnValue
370
430
  end
371
- klass.new var_gen, name, type
431
+ klass.new var_gen, name, type, direction
372
432
  else
373
- builder_for_field_getter var_gen, name, type
433
+ builder_for_field_getter var_gen, name, type, direction
374
434
  end
375
435
  end
376
436
 
377
- def self.builder_for_field_getter var_gen, name, type
437
+ def self.builder_for_field_getter var_gen, name, type, direction
378
438
  klass = case type.tag
379
439
  when :void
380
440
  if type.pointer?
@@ -385,33 +445,27 @@ module GirFFI::Builder
385
445
  when :interface
386
446
  case type.interface.info_type
387
447
  when :struct, :union, :interface, :object
388
- InterfaceReturnValue
448
+ WrappingReturnValue
389
449
  else
390
450
  RegularReturnValue
391
451
  end
392
452
  when :array
393
453
  if type.zero_terminated?
394
- StrvReturnValue
454
+ WrappingReturnValue
395
455
  else
396
456
  case type.array_type
397
457
  when :c
398
458
  CArrayReturnValue
399
459
  when :array
400
- it = ReturnValue.new var_gen, name, type
460
+ it = ReturnValue.new var_gen, name, type, direction
401
461
  it.extend WithTypedContainerPostMethod
402
462
  return it
403
- when :byte_array
404
- ByteArrayReturnValue
405
463
  else
406
- PtrArrayReturnValue
464
+ WrappingReturnValue
407
465
  end
408
466
  end
409
- when :glist, :gslist
410
- it = ReturnValue.new var_gen, name, type
411
- it.extend WithTypedContainerPostMethod
412
- return it
413
- when :ghash
414
- it = ReturnValue.new var_gen, name, type
467
+ when :glist, :gslist, :ghash
468
+ it = ReturnValue.new var_gen, name, type, direction
415
469
  it.extend WithTypedContainerPostMethod
416
470
  return it
417
471
  when :utf8
@@ -419,7 +473,7 @@ module GirFFI::Builder
419
473
  else
420
474
  RegularReturnValue
421
475
  end
422
- klass.new var_gen, name, type
476
+ klass.new var_gen, name, type, direction
423
477
  end
424
478
  end
425
479
 
@@ -447,14 +501,16 @@ module GirFFI::Builder
447
501
  # Implements argument processing for interface return values (interfaces
448
502
  # and structs, but not objects, which need special handling for
449
503
  # polymorphism and constructors).
450
- class InterfaceReturnValue < ReturnValue
451
- def post
452
- [ "#{retname} = #{argument_class_name}.wrap(#{cvar})" ]
453
- end
454
- end
455
-
456
- # Implements argument processing for object return values.
457
- class ObjectReturnValue < ReturnValue
504
+ #
505
+ # Implements argument processing for object return values when the method is
506
+ # not a constructor.
507
+ #
508
+ # Implements argument processing for NULL-terminated string array return values.
509
+ #
510
+ # Implements argument processing for GByteArray return values.
511
+ #
512
+ # Implements argument processing for GPtrArray return values.
513
+ class WrappingReturnValue < ReturnValue
458
514
  def post
459
515
  [ "#{retname} = #{argument_class_name}.wrap(#{cvar})" ]
460
516
  end
@@ -476,13 +532,6 @@ module GirFFI::Builder
476
532
  end
477
533
  end
478
534
 
479
- # Implements argument processing for NULL-terminated string array return values.
480
- class StrvReturnValue < ReturnValue
481
- def post
482
- [ "#{retname} = GLib::Strv.wrap(#{cvar})" ]
483
- end
484
- end
485
-
486
535
  # Implements argument processing for UTF8 string return values.
487
536
  class Utf8ReturnValue < ReturnValue
488
537
  def post
@@ -490,20 +539,6 @@ module GirFFI::Builder
490
539
  end
491
540
  end
492
541
 
493
- # Implements argument processing for GByteArray return values.
494
- class ByteArrayReturnValue < ReturnValue
495
- def post
496
- [ "#{retname} = GLib::ByteArray.wrap(#{cvar})" ]
497
- end
498
- end
499
-
500
- # Implements argument processing for GPtrArray return values.
501
- class PtrArrayReturnValue < ReturnValue
502
- def post
503
- [ "#{retname} = GLib::PtrArray.wrap(#{cvar})" ]
504
- end
505
- end
506
-
507
542
  # Implements argument processing for other return values.
508
543
  class RegularReturnValue < ReturnValue
509
544
  def retval
@@ -45,13 +45,13 @@ module GirFFI
45
45
 
46
46
  def return_value_builder
47
47
  @rv_builder ||= ReturnValueFactory.builder_for_field_getter(
48
- VariableNameGenerator.new, @info.name, @info.field_type)
48
+ VariableNameGenerator.new, @info.name, @info.field_type, :return)
49
49
  end
50
50
 
51
51
  def setter_builder
52
52
  type = @info.field_type
53
53
  vargen = VariableNameGenerator.new
54
- Builder::InArgument.builder_for vargen, "value", type, @libmodule
54
+ Builder::InArgument.builder_for vargen, "value", type, :in, @libmodule
55
55
  end
56
56
  end
57
57
  end
@@ -37,7 +37,7 @@ module GirFFI::Builder
37
37
 
38
38
  def setup_error_argument vargen
39
39
  klass = @info.throws? ? ErrorArgument : NullArgument
40
- @errarg = klass.new vargen, nil, nil
40
+ @errarg = klass.new vargen, nil, nil, :error
41
41
  end
42
42
 
43
43
  def filled_out_template
@@ -26,19 +26,6 @@ module GirFFI
26
26
  ArgHelper.ptr_to_typed_array @sub_type, block, size
27
27
  end
28
28
 
29
- private
30
-
31
- def adjust_value_out value
32
- case @value_type
33
- when :gboolean
34
- (value != 0)
35
- when :utf8
36
- ArgHelper.ptr_to_utf8 value
37
- else
38
- value
39
- end
40
- end
41
-
42
29
  def self.for type, sub_type=nil
43
30
  ffi_type = TypeMap.map_basic_type_or_string type
44
31
  ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
@@ -47,6 +34,11 @@ module GirFFI
47
34
  end
48
35
 
49
36
  def self.from type, value, sub_type=nil
37
+ if Array === type
38
+ arr_t, sub_t = *type
39
+ # TODO: Take array type into account (zero-terminated or not)
40
+ return self.from_array sub_t, value
41
+ end
50
42
  value = adjust_value_in type, value
51
43
  ffi_type = TypeMap.map_basic_type_or_string type
52
44
  ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
@@ -85,6 +77,20 @@ module GirFFI
85
77
  end
86
78
  end
87
79
  end
80
+
81
+ private
82
+
83
+ def adjust_value_out value
84
+ case @value_type
85
+ when :gboolean
86
+ (value != 0)
87
+ when :utf8
88
+ ArgHelper.ptr_to_utf8 value
89
+ else
90
+ value
91
+ end
92
+ end
93
+
88
94
  end
89
95
  end
90
96
 
@@ -18,6 +18,10 @@ module GirFFI
18
18
  def self.from type, val
19
19
  return nil if val.nil?
20
20
  case type
21
+ when Array
22
+ arr_t, sub_t = *type
23
+ # TODO: Take array type into account (zero-terminated or not)
24
+ self.from_array sub_t, val
21
25
  when :utf8, :filename
22
26
  from_utf8 val
23
27
  when :gint32, :gint8
@@ -0,0 +1,14 @@
1
+ require 'gir_ffi/builder_helper'
2
+
3
+ module GirFFI
4
+ module InfoExt
5
+ module IRegisteredTypeInfo
6
+ def full_type_name
7
+ "::#{safe_namespace}::#{name}"
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ GObjectIntrospection::IRegisteredTypeInfo.send :include, GirFFI::InfoExt::IRegisteredTypeInfo
14
+
@@ -24,6 +24,61 @@ module GirFFI
24
24
  end
25
25
  end
26
26
 
27
+ def element_type
28
+ case tag
29
+ when :glist, :gslist, :array
30
+ subtype_tag 0
31
+ when :ghash
32
+ [subtype_tag(0), subtype_tag(1)]
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ def interface_type_name
39
+ interface.full_type_name
40
+ end
41
+
42
+ def type_specification
43
+ tag = self.tag
44
+ if tag == :array
45
+ "[#{flattened_array_type.inspect}, #{element_type.inspect}]"
46
+ else
47
+ tag.inspect
48
+ end
49
+ end
50
+
51
+ def flattened_tag
52
+ case tag
53
+ when :interface
54
+ interface_type
55
+ when :array
56
+ flattened_array_type
57
+ else
58
+ tag
59
+ end
60
+ end
61
+
62
+ def interface_type
63
+ interface.info_type
64
+ end
65
+
66
+ def flattened_array_type
67
+ if zero_terminated?
68
+ if element_type == :utf8
69
+ :strv
70
+ else
71
+ # TODO: Check that array_type == :c
72
+ # TODO: Perhaps distinguish :c from zero-terminated :c
73
+ :c
74
+ end
75
+ else
76
+ array_type
77
+ end
78
+ end
79
+
80
+ private
81
+
27
82
  def subtype_tag index
28
83
  st = param_type(index)
29
84
  tag = st.tag
@@ -38,17 +93,6 @@ module GirFFI
38
93
  return tag
39
94
  end
40
95
  end
41
-
42
- def element_type
43
- case tag
44
- when :glist, :gslist, :array
45
- subtype_tag 0
46
- when :ghash
47
- [subtype_tag(0), subtype_tag(1)]
48
- else
49
- nil
50
- end
51
- end
52
96
  end
53
97
  end
54
98
  end
@@ -1,4 +1,4 @@
1
1
  module GirFFI
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
4
4
 
@@ -9,7 +9,7 @@ describe GirFFI::Builder::Argument::Base do
9
9
 
10
10
  mock(info = Object.new).param_type(0) { subtype }
11
11
 
12
- builder = GirFFI::Builder::Argument::Base.new nil, 'foo', info
12
+ builder = GirFFI::Builder::Argument::Base.new nil, 'foo', info, :direction
13
13
  assert_equal ":void", builder.subtype_tag_or_class_name
14
14
  end
15
15
  end
@@ -21,24 +21,21 @@ describe GirFFI::Builder::Argument::Base do
21
21
 
22
22
  mock(info = Object.new).param_type(0) { subtype }
23
23
 
24
- builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
24
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
25
25
  assert_equal ":foo", builder.subtype_tag_or_class_name
26
26
  end
27
27
  end
28
28
 
29
- describe "for an array of interface class Foo::Bar" do
30
- it "returns the string '::Foo::Bar'" do
31
- mock(interface = Object.new).safe_namespace { "Foo" }
32
- mock(interface).name { "Bar" }
33
-
29
+ describe "for an array of an interface class" do
30
+ it "returns the interface's full class name" do
34
31
  mock(subtype = Object.new).tag { :interface }
35
- mock(subtype).interface { interface }
32
+ mock(subtype).interface_type_name { "-full-type-name-" }
36
33
  mock(subtype).pointer? { false }
37
34
 
38
35
  mock(info = Object.new).param_type(0) { subtype }
39
36
 
40
- builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
41
- assert_equal "::Foo::Bar", builder.subtype_tag_or_class_name
37
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
38
+ assert_equal "-full-type-name-", builder.subtype_tag_or_class_name
42
39
  end
43
40
  end
44
41
 
@@ -49,11 +46,10 @@ describe GirFFI::Builder::Argument::Base do
49
46
 
50
47
  mock(info = Object.new).param_type(0) { subtype }
51
48
 
52
- builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info
49
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, :direction
53
50
  assert_equal "[:pointer, :foo]", builder.subtype_tag_or_class_name
54
51
  end
55
52
  end
56
-
57
53
  end
58
54
  end
59
55
 
@@ -38,7 +38,7 @@ describe GirFFI::Builder::Function do
38
38
  def self.test_array_gint16_in ints
39
39
  n_ints = ints.nil? ? 0 : ints.length
40
40
  _v1 = n_ints
41
- _v2 = GirFFI::InPointer.from_array :gint16, ints
41
+ _v2 = GirFFI::InPointer.from([:c, :gint16], ints)
42
42
  _v3 = DummyLib.regress_test_array_gint16_in _v1, _v2
43
43
  return _v3
44
44
  end
@@ -56,7 +56,7 @@ describe GirFFI::Builder::Function do
56
56
  def self.test_callback_destroy_notify callback, user_data, notify
57
57
  _v1 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"Regress\", \"TestCallbackUserData\", callback
58
58
  DummyLib::CALLBACKS << _v1
59
- _v2 = GirFFI::InPointer.from :void, user_data
59
+ _v2 = GirFFI::InPointer.from(:void, user_data)
60
60
  _v3 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"GLib\", \"DestroyNotify\", notify
61
61
  DummyLib::CALLBACKS << _v3
62
62
  _v4 = DummyLib.regress_test_callback_destroy_notify _v1, _v2, _v3
@@ -74,7 +74,7 @@ describe GirFFI::Builder::Function do
74
74
 
75
75
  expected = <<-CODE
76
76
  def self.new_from_file x
77
- _v1 = GirFFI::InPointer.from :utf8, x
77
+ _v1 = GirFFI::InPointer.from(:utf8, x)
78
78
  _v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil
79
79
  _v3 = DummyLib.regress_test_obj_new_from_file _v1, _v2
80
80
  GirFFI::ArgHelper.check_error(_v2)
@@ -93,7 +93,7 @@ describe GirFFI::Builder::Function do
93
93
 
94
94
  expected = <<-CODE
95
95
  def self.gvalue_in value
96
- _v1 = ::GObject::Value.from value
96
+ _v1 = ::GObject::Value.from(value)
97
97
  DummyLib.gi_marshalling_tests_gvalue_in _v1
98
98
 
99
99
  end
@@ -109,7 +109,7 @@ describe GirFFI::Builder::Function do
109
109
 
110
110
  expected = <<-CODE
111
111
  def self.test_array_int_null_in arr
112
- _v1 = GirFFI::InPointer.from_array :gint32, arr
112
+ _v1 = GirFFI::InPointer.from([:c, :gint32], arr)
113
113
  len = arr.nil? ? 0 : arr.length
114
114
  _v2 = len
115
115
  DummyLib.regress_test_array_int_null_in _v1, _v2
@@ -64,6 +64,7 @@ describe GirFFI::Builder::Type::Struct do
64
64
 
65
65
  stub(type = Object.new).pointer? { false }
66
66
  stub(type).tag { :gint32 }
67
+ stub(type).flattened_tag { :gint32 }
67
68
 
68
69
  stub(@field).field_type { type }
69
70
  stub(@field).name { "bar" }
@@ -21,19 +21,6 @@ describe GirFFI::InfoExt::ITypeInfo do
21
21
  end
22
22
  end
23
23
 
24
- describe "#subtype_tag" do
25
- it "returns :gpointer if the param_type is a pointer with tag :void" do
26
- type_info = testclass.new
27
-
28
- stub(subtype0 = Object.new).tag { :void }
29
- stub(subtype0).pointer? { true }
30
-
31
- mock(type_info).param_type(0) { subtype0 }
32
-
33
- assert_equal :gpointer, type_info.subtype_tag(0)
34
- end
35
- end
36
-
37
24
  describe "#element_type" do
38
25
  it "returns the element type for lists" do
39
26
  type_info = testclass.new
@@ -67,5 +54,38 @@ describe GirFFI::InfoExt::ITypeInfo do
67
54
  result = type_info.element_type
68
55
  result.must_be_nil
69
56
  end
57
+
58
+ it "returns :gpointer if the element type is a pointer with tag :void" do
59
+ type_info = testclass.new
60
+
61
+ stub(elm_type = Object.new).tag { :void }
62
+ stub(elm_type).pointer? { true }
63
+
64
+ mock(type_info).tag {:glist}
65
+ mock(type_info).param_type(0) { elm_type }
66
+
67
+ assert_equal :gpointer, type_info.element_type
68
+ end
69
+ end
70
+
71
+ describe "#type_specification" do
72
+ describe "for a simple type" do
73
+ it "returns the type tag" do
74
+ type_info = testclass.new
75
+ mock(type_info).tag { :uint32 }
76
+ type_info.type_specification.must_equal ":uint32"
77
+ end
78
+ end
79
+
80
+ describe "for a zero-terminated array" do
81
+ it "returns the pair [:strv, element_type]" do
82
+ type_info = testclass.new
83
+ mock(type_info).tag { :array }
84
+ stub(type_info).element_type { :utf8 }
85
+ stub(type_info).zero_terminated? { true }
86
+ stub(type_info).array_type { :c }
87
+ type_info.type_specification.must_equal "[:strv, :utf8]"
88
+ end
89
+ end
70
90
  end
71
91
  end
@@ -490,20 +490,24 @@ describe "GIMarshallingTests" do
490
490
  assert_equal [-1, 0, 1, 2], res
491
491
  end
492
492
 
493
- it "has a working function #array_gvariant_(none)_in" do
494
- v1 = GLib::Variant.new_int32(27)
495
- v2 = GLib::Variant.new_string("Hello")
496
- if GIMarshallingTests._builder.setup_method :array_gvariant_in
497
- GIMarshallingTests.array_gvariant_in [v1, v2]
498
- else
499
- GIMarshallingTests.array_gvariant_none_in [v1, v2]
500
- end
501
-
502
- pass
503
- # TODO: Can we determine that result should be an array?
504
- # assert_equal 27, res[0].get_int32
505
- # assert_equal "Hello", res[1].get_string
506
- end
493
+ it "has a working function #array_gvariant_(none)_in"
494
+ # FIXME: Test was disabled since the implementation of the return value
495
+ # handling was never correct.
496
+ #
497
+ #do
498
+ #v1 = GLib::Variant.new_int32(27)
499
+ #v2 = GLib::Variant.new_string("Hello")
500
+ #if GIMarshallingTests._builder.setup_method :array_gvariant_in
501
+ #GIMarshallingTests.array_gvariant_in [v1, v2]
502
+ #else
503
+ #GIMarshallingTests.array_gvariant_none_in [v1, v2]
504
+ #end
505
+
506
+ #pass
507
+ ## TODO: Can we determine that result should be an array?
508
+ ## assert_equal 27, res[0].get_int32
509
+ ## assert_equal "Hello", res[1].get_string
510
+ #end
507
511
 
508
512
  it "has a working function #array_in" do
509
513
  GIMarshallingTests.array_in [-1, 0, 1, 2]
data/test/lib/Makefile.am CHANGED
@@ -19,7 +19,7 @@ libgimarshallingtests_la_LDFLAGS = -module -avoid-version
19
19
  # g-i doesn't ship these as shared libraries anymore; we build them here
20
20
  Regress-1.0.gir: libregress.la Makefile
21
21
  $(AM_V_GEN) g-ir-scanner --include=cairo-1.0 --include=Gio-2.0 \
22
- --namespace=Regress --nsversion=1.0 \
22
+ --namespace=Regress --nsversion=1.0 --pkg=cairo-gobject \
23
23
  --warn-all --warn-error \
24
24
  --library=libregress.la \
25
25
  --libtool="$(top_builddir)/libtool" \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gir_ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-22 00:00:00.000000000 Z
12
+ date: 2012-11-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -150,6 +150,7 @@ files:
150
150
  - lib/gir_ffi/info_ext/i_type_info.rb
151
151
  - lib/gir_ffi/info_ext/i_field_info.rb
152
152
  - lib/gir_ffi/info_ext/i_property_info.rb
153
+ - lib/gir_ffi/info_ext/i_registered_type_info.rb
153
154
  - lib/gir_ffi/module_base.rb
154
155
  - lib/gir_ffi/class_base.rb
155
156
  - lib/gir_ffi/object_base.rb
@@ -169,6 +170,7 @@ files:
169
170
  - lib/ffi-glib/list.rb
170
171
  - lib/ffi-glib/hash_table.rb
171
172
  - lib/ffi-glib/list_methods.rb
173
+ - lib/ffi-glib/strv.rb
172
174
  - lib/ffi-glib/byte_array.rb
173
175
  - lib/ffi-glib/ptr_array.rb
174
176
  - lib/ffi-glib/s_list.rb