gir_ffi 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/History.txt +5 -0
  2. data/lib/ffi-glib/array.rb +2 -3
  3. data/lib/ffi-glib/container_class_methods.rb +3 -4
  4. data/lib/ffi-glib/hash_table.rb +7 -3
  5. data/lib/ffi-glib/list_methods.rb +1 -1
  6. data/lib/ffi-glib/sized_array.rb +66 -0
  7. data/lib/ffi-glib/strv.rb +1 -1
  8. data/lib/ffi-glib.rb +5 -4
  9. data/lib/ffi-gobject/object.rb +2 -3
  10. data/lib/ffi-gobject/ruby_closure.rb +3 -2
  11. data/lib/ffi-gobject/value.rb +26 -14
  12. data/lib/ffi-gobject.rb +8 -5
  13. data/lib/ffi-gobject_introspection/g_error.rb +1 -0
  14. data/lib/ffi-gobject_introspection/i_base_info.rb +3 -2
  15. data/lib/ffi-gobject_introspection/i_union_info.rb +21 -8
  16. data/lib/ffi-gobject_introspection/lib.rb +1 -0
  17. data/lib/gir_ffi/argument_builder.rb +8 -20
  18. data/lib/gir_ffi/base_argument_builder.rb +13 -30
  19. data/lib/gir_ffi/builder/module.rb +3 -9
  20. data/lib/gir_ffi/builder/type/base.rb +2 -0
  21. data/lib/gir_ffi/builder/type/callback.rb +2 -2
  22. data/lib/gir_ffi/builder/type/enum.rb +1 -0
  23. data/lib/gir_ffi/builder/type/object.rb +13 -3
  24. data/lib/gir_ffi/builder/type/registered_type.rb +1 -1
  25. data/lib/gir_ffi/builder/type/struct.rb +18 -3
  26. data/lib/gir_ffi/builder/type/unintrospectable.rb +5 -45
  27. data/lib/gir_ffi/builder/type/user_defined.rb +3 -15
  28. data/lib/gir_ffi/builder/type.rb +5 -5
  29. data/lib/gir_ffi/builder.rb +5 -80
  30. data/lib/gir_ffi/callback.rb +65 -2
  31. data/lib/gir_ffi/callback_helper.rb +0 -56
  32. data/lib/gir_ffi/class_base.rb +2 -2
  33. data/lib/gir_ffi/in_out_pointer.rb +7 -28
  34. data/lib/gir_ffi/in_pointer.rb +12 -19
  35. data/lib/gir_ffi/info_ext/i_arg_info.rb +5 -0
  36. data/lib/gir_ffi/info_ext/i_callable_info.rb +16 -0
  37. data/lib/gir_ffi/info_ext/i_function_info.rb +15 -0
  38. data/lib/gir_ffi/info_ext/i_signal_info.rb +17 -10
  39. data/lib/gir_ffi/info_ext/i_type_info.rb +63 -39
  40. data/lib/gir_ffi/info_ext.rb +5 -3
  41. data/lib/gir_ffi/null_argument_builder.rb +1 -1
  42. data/lib/gir_ffi/return_value_builder.rb +24 -16
  43. data/lib/gir_ffi/unintrospectable_type_info.rb +41 -0
  44. data/lib/gir_ffi/user_defined_property_info.rb +15 -0
  45. data/lib/gir_ffi/user_defined_type_info.rb +25 -0
  46. data/lib/gir_ffi/version.rb +1 -1
  47. data/lib/gir_ffi-base.rb +3 -0
  48. data/lib/gir_ffi.rb +2 -1
  49. data/test/ffi-glib/sized_array_test.rb +87 -0
  50. data/test/ffi-gobject_introspection/i_base_info_test.rb +4 -5
  51. data/test/gir_ffi/argument_builder_test.rb +26 -55
  52. data/test/gir_ffi/builder/type/unintrospectable_test.rb +3 -19
  53. data/test/gir_ffi/builder/type/user_defined_test.rb +16 -21
  54. data/test/gir_ffi/builder_test.rb +31 -53
  55. data/test/gir_ffi/callback_helper_test.rb +0 -47
  56. data/test/gir_ffi/callback_test.rb +49 -0
  57. data/test/gir_ffi/function_builder_test.rb +8 -8
  58. data/test/gir_ffi/in_out_pointer_test.rb +2 -53
  59. data/test/gir_ffi/in_pointer_test.rb +0 -13
  60. data/test/gir_ffi/info_ext/i_callable_info_test.rb +32 -0
  61. data/test/gir_ffi/info_ext/i_function_info_test.rb +61 -0
  62. data/test/gir_ffi/info_ext/i_signal_info_test.rb +7 -0
  63. data/test/gir_ffi/info_ext/i_type_info_test.rb +158 -77
  64. data/test/gir_ffi/return_value_builder_test.rb +2 -2
  65. data/test/gir_ffi/unintrospectable_type_info_test.rb +95 -0
  66. data/test/gir_ffi/user_defined_property_info_test.rb +19 -0
  67. data/test/gir_ffi/user_defined_type_info_test.rb +34 -0
  68. data/test/integration/generated_gimarshallingtests_test.rb +10 -10
  69. data/test/integration/generated_regress_test.rb +10 -10
  70. metadata +24 -15
  71. data/lib/gir_ffi/builder/type/struct_based.rb +0 -31
  72. data/lib/gir_ffi/user_defined/i_base_info.rb +0 -7
  73. data/lib/gir_ffi/user_defined/i_object_info.rb +0 -13
  74. data/lib/gir_ffi/user_defined/i_property_info.rb +0 -9
  75. data/lib/gir_ffi/user_defined/i_registered_type_info.rb +0 -10
  76. data/test/gir_ffi/user_defined/i_object_info_test.rb +0 -18
  77. data/test/gir_ffi/user_defined/i_property_info_test.rb +0 -14
  78. data/test/gir_ffi/user_defined/i_registered_type_info_test.rb +0 -10
@@ -41,7 +41,7 @@ module GirFFI
41
41
  return if info.find_method 'new'
42
42
 
43
43
  (class << @klass; self; end).class_eval {
44
- alias_method :new, :allocate
44
+ alias_method :new, :_allocate
45
45
  }
46
46
  end
47
47
 
@@ -1,16 +1,31 @@
1
- require 'gir_ffi/builder/type/struct_based'
1
+ require 'gir_ffi/builder/type/registered_type'
2
+ require 'gir_ffi/builder/type/with_layout'
3
+ require 'gir_ffi/builder/type/with_methods'
4
+
2
5
  module GirFFI
3
6
  module Builder
4
7
  module Type
5
8
 
6
9
  # Implements the creation of a class representing a Struct.
7
- class Struct < StructBased
10
+ class Struct < RegisteredType
11
+ include WithMethods
12
+ include WithLayout
13
+
8
14
  private
9
15
 
10
16
  def setup_class
11
- super
17
+ setup_layout
18
+ setup_constants
19
+ stub_methods
20
+ setup_gtype_getter
21
+ setup_field_accessors
12
22
  provide_constructor
13
23
  end
24
+
25
+ # FIXME: Private method only in subclass
26
+ def layout_superclass
27
+ FFI::Struct
28
+ end
14
29
  end
15
30
  end
16
31
  end
@@ -1,4 +1,5 @@
1
1
  require 'gir_ffi/builder/type/object'
2
+
2
3
  module GirFFI
3
4
  module Builder
4
5
  module Type
@@ -7,23 +8,14 @@ module GirFFI
7
8
  # which no data is found in the GIR. Typically, these are created to
8
9
  # cast objects returned by a function that returns an interface.
9
10
  class Unintrospectable < Object
10
- # FIXME: Breaks parent interface.
11
- def initialize gtype
12
- @gtype = gtype
13
- @info = nil
14
- end
15
-
16
11
  def instantiate_class
17
- CACHE[@gtype] ||= Class.new(superclass)
18
- @klass = CACHE[@gtype]
12
+ gtype = target_gtype
13
+ CACHE[gtype] ||= Class.new(superclass)
14
+ @klass = CACHE[gtype]
19
15
  @structklass = get_or_define_class @klass, :Struct, layout_superclass
20
16
  setup_class unless already_set_up
21
17
  end
22
18
 
23
- def target_gtype
24
- @gtype
25
- end
26
-
27
19
  def setup_class
28
20
  setup_constants
29
21
  setup_layout
@@ -37,40 +29,8 @@ module GirFFI
37
29
 
38
30
  private
39
31
 
40
- def superclass
41
- GirFFI::Builder.build_by_gtype parent_gtype
42
- end
43
-
44
- def parent
45
- gir.find_by_gtype parent_gtype
46
- end
47
-
48
- def parent_gtype
49
- GObject.type_parent @gtype
50
- end
51
-
52
- def fields
53
- []
54
- end
55
-
56
- def interface_infos
57
- interface_gtypes.map do |gtype|
58
- gir.find_by_gtype gtype
59
- end.compact
60
- end
61
-
62
- def interface_gtypes
63
- ::GObject.type_interfaces(@gtype)
64
- end
65
-
66
- def interfaces
67
- interface_infos.map do |info|
68
- GirFFI::Builder.build_class info
69
- end
70
- end
71
-
72
32
  def signal_definers
73
- interface_infos
33
+ info.interfaces
74
34
  end
75
35
  end
76
36
  end
@@ -1,5 +1,3 @@
1
- require 'gir_ffi/user_defined/i_object_info'
2
- require 'gir_ffi/user_defined/i_property_info'
3
1
  require 'gir_ffi/builder/type/object'
4
2
 
5
3
  module GirFFI
@@ -8,16 +6,12 @@ module GirFFI
8
6
 
9
7
  # Implements the creation of GObject subclasses from Ruby.
10
8
  class UserDefined < Object
11
- def initialize klass, &block
12
- @block = block
13
- @klass_before_set_up = klass
9
+ def initialize info
10
+ @info = info
14
11
  end
15
12
 
16
13
  def instantiate_class
17
- @klass = @klass_before_set_up
18
- @info = GirFFI::UserDefined::IObjectInfo.new
19
-
20
- self.instance_eval(&@block) if @block
14
+ @klass = @info.described_class
21
15
 
22
16
  parent_type = @klass.get_gtype
23
17
  @parent = gir.find_by_gtype(parent_type)
@@ -59,12 +53,6 @@ module GirFFI
59
53
  @parent
60
54
  end
61
55
 
62
- def install_property pspec
63
- pinfo = GirFFI::UserDefined::IPropertyInfo.new
64
- pinfo.name = pspec.get_name
65
- properties << pinfo
66
- end
67
-
68
56
  def properties
69
57
  info.properties
70
58
  end
@@ -1,12 +1,11 @@
1
- require 'gir_ffi/builder_helper'
2
- require 'gir_ffi/builder/type/base'
3
1
  require 'gir_ffi/builder/type/callback'
4
2
  require 'gir_ffi/builder/type/constant'
5
3
  require 'gir_ffi/builder/type/enum'
6
- require 'gir_ffi/builder/type/union'
4
+ require 'gir_ffi/builder/type/interface'
7
5
  require 'gir_ffi/builder/type/object'
8
6
  require 'gir_ffi/builder/type/struct'
9
- require 'gir_ffi/builder/type/interface'
7
+ require 'gir_ffi/builder/type/unintrospectable'
8
+ require 'gir_ffi/builder/type/union'
10
9
 
11
10
  module GirFFI
12
11
  # Builds a class based on information found in the introspection
@@ -23,7 +22,8 @@ module GirFFI
23
22
  :interface => Interface,
24
23
  :object => Object,
25
24
  :struct => Struct,
26
- :union => Union
25
+ :union => Union,
26
+ :unintrospectable => Unintrospectable
27
27
  }
28
28
 
29
29
  def self.build info
@@ -1,7 +1,7 @@
1
1
  require 'gir_ffi/builder/type'
2
- require 'gir_ffi/builder/type/unintrospectable'
3
2
  require 'gir_ffi/builder/module'
4
3
  require 'gir_ffi/builder_helper'
4
+ require 'gir_ffi/unintrospectable_type_info'
5
5
 
6
6
  module GirFFI
7
7
  # Builds modules and classes based on information found in the
@@ -16,96 +16,21 @@ module GirFFI
16
16
 
17
17
  def self.build_by_gtype gtype
18
18
  info = GObjectIntrospection::IRepository.default.find_by_gtype gtype
19
- if info.nil?
20
- Builder::Type::Unintrospectable.new(gtype).build_class
21
- else
22
- build_class info
23
- end
19
+ info ||= UnintrospectableTypeInfo.new gtype
20
+
21
+ build_class info
24
22
  end
25
23
 
26
24
  def self.build_module namespace, version=nil
27
25
  Builder::Module.new(namespace, version).generate
28
26
  end
29
27
 
30
- def self.build_module_non_recursive namespace, version=nil
31
- Builder::Module.new(namespace, version).build_module_non_recursive
32
- end
33
-
34
- def self.build_callback callable_info, &block
35
- rettype = ffi_callback_return_type callable_info
36
- argtypes = ffi_callback_argument_types callable_info
37
-
38
- FFI::Function.new rettype, argtypes, &block
39
- end
40
-
41
28
  # TODO: Move elsewhere, perhaps to Builder::Function.
42
29
  def self.attach_ffi_function lib, info
43
30
  sym = info.symbol
44
31
  return if lib.method_defined? sym
45
- argtypes = ffi_function_argument_types info
46
- rt = ffi_function_return_type info
47
-
48
- lib.attach_function sym, argtypes, rt
49
- end
50
-
51
- def self.ffi_function_argument_types info
52
- types = info.args.map { |arg| iarginfo_to_ffitype arg }
53
-
54
- if info.info_type == :function
55
- types.unshift :pointer if info.method?
56
- types << :pointer if info.throws?
57
- end
58
-
59
- types
60
- end
61
-
62
- def self.ffi_callback_argument_types info
63
- types = info.args.map do |arg|
64
- itypeinfo_to_callback_ffitype arg.argument_type
65
- end
66
- types.unshift(:pointer).push(:pointer)
67
- end
68
-
69
- def self.ffi_callback_return_type info
70
- ffi_function_return_type info
71
- end
72
-
73
- def self.ffi_function_return_type info
74
- itypeinfo_to_ffitype info.return_type
75
- end
76
-
77
- def self.itypeinfo_to_callback_ffitype info
78
- tag = info.tag
79
-
80
- return :string if tag == :utf8
81
- return :pointer if info.pointer?
82
-
83
- if tag == :interface
84
- case info.interface.info_type
85
- when :enum, :flags
86
- :int32
87
- else
88
- :pointer
89
- end
90
- else
91
- return TypeMap.map_basic_type tag
92
- end
93
- end
94
-
95
- def self.itypeinfo_to_ffitype info
96
- return :pointer if info.pointer?
97
-
98
- tag = info.tag
99
- if tag == :interface
100
- return build_class info.interface
101
- else
102
- return TypeMap.map_basic_type tag
103
- end
104
- end
105
32
 
106
- def self.iarginfo_to_ffitype info
107
- return :pointer if info.direction != :in
108
- return itypeinfo_to_ffitype info.argument_type
33
+ lib.attach_function sym, info.argument_ffi_types, info.return_ffi_type
109
34
  end
110
35
  end
111
36
  end
@@ -1,9 +1,72 @@
1
1
  module GirFFI
2
+ # Specialized kind of Proc to be used for callback arguments.
3
+ # TODO: Create superclass for all actual callback types that does the wrapping for this.
2
4
  class Callback < Proc
5
+ # Create Callback from a Proc. Makes sure arguments are properly wrapped,
6
+ # and the callback is stored to prevent garbage collection.
3
7
  def self.from namespace, name, prc
4
- GirFFI::CallbackHelper.wrap_in_callback_args_mapper(namespace, name, prc).tap do |cb|
5
- GirFFI::CallbackHelper.store_callback cb
8
+ wrap_in_callback_args_mapper(namespace, name, prc).tap do |cb|
9
+ CallbackHelper.store_callback cb
6
10
  end
7
11
  end
12
+
13
+ # TODO: Create actual callback class from the callback info, so no lookup
14
+ # is needed. This class can then also perform the argument mapping.
15
+ def self.wrap_in_callback_args_mapper namespace, name, prc
16
+ return prc if FFI::Function === prc
17
+ return nil if prc.nil?
18
+ info = GObjectIntrospection::IRepository.default.find_by_name namespace, name
19
+ return self.new do |*args|
20
+ prc.call(*map_callback_args(args, info))
21
+ end
22
+ end
23
+
24
+ def self.map_callback_args args, info
25
+ args.zip(info.args).map { |arg, inf|
26
+ map_single_callback_arg arg, inf.argument_type }
27
+ end
28
+
29
+ # TODO: Use GirFFI::ReturnValue classes for mapping.
30
+ def self.map_single_callback_arg arg, type
31
+ case type.tag
32
+ when :interface
33
+ map_interface_callback_arg arg, type
34
+ when :utf8
35
+ ArgHelper.ptr_to_utf8 arg
36
+ when :void
37
+ map_void_callback_arg arg
38
+ when :array
39
+ subtype = type.param_type(0)
40
+ if subtype.tag == :interface and arg.is_a?(FFI::Pointer)
41
+ map_interface_callback_arg arg, subtype
42
+ else
43
+ raise NotImplementedError
44
+ end
45
+ else
46
+ arg
47
+ end
48
+ end
49
+
50
+ def self.map_interface_callback_arg arg, type
51
+ iface = type.interface
52
+ case iface.info_type
53
+ when :object, :interface
54
+ arg.to_object
55
+ when :struct
56
+ klass = GirFFI::Builder.build_class iface
57
+ klass.wrap arg
58
+ else
59
+ arg
60
+ end
61
+ end
62
+
63
+ def self.map_void_callback_arg arg
64
+ if arg.null?
65
+ nil
66
+ else
67
+ GirFFI::ArgHelper::OBJECT_STORE[arg.address]
68
+ end
69
+ end
70
+
8
71
  end
9
72
  end
@@ -3,62 +3,6 @@ module GirFFI
3
3
  module CallbackHelper
4
4
  CALLBACKS = []
5
5
 
6
- def self.wrap_in_callback_args_mapper namespace, name, prc
7
- return prc if FFI::Function === prc
8
- return nil if prc.nil?
9
- info = GObjectIntrospection::IRepository.default.find_by_name namespace, name
10
- return Callback.new do |*args|
11
- prc.call(*map_callback_args(args, info))
12
- end
13
- end
14
-
15
- def self.map_callback_args args, info
16
- args.zip(info.args).map { |arg, inf|
17
- map_single_callback_arg arg, inf.argument_type }
18
- end
19
-
20
- # TODO: Use GirFFI::ReturnValue classes for mapping.
21
- def self.map_single_callback_arg arg, type
22
- case type.tag
23
- when :interface
24
- map_interface_callback_arg arg, type
25
- when :utf8
26
- ArgHelper.ptr_to_utf8 arg
27
- when :void
28
- map_void_callback_arg arg
29
- when :array
30
- subtype = type.param_type(0)
31
- if subtype.tag == :interface and arg.is_a?(FFI::Pointer)
32
- map_interface_callback_arg arg, subtype
33
- else
34
- raise NotImplementedError
35
- end
36
- else
37
- arg
38
- end
39
- end
40
-
41
- def self.map_interface_callback_arg arg, type
42
- iface = type.interface
43
- case iface.info_type
44
- when :object, :interface
45
- arg.to_object
46
- when :struct
47
- klass = GirFFI::Builder.build_class iface
48
- klass.wrap arg
49
- else
50
- arg
51
- end
52
- end
53
-
54
- def self.map_void_callback_arg arg
55
- if arg.null?
56
- nil
57
- else
58
- GirFFI::ArgHelper::OBJECT_STORE[arg.address]
59
- end
60
- end
61
-
62
6
  def self.store_callback prc
63
7
  CALLBACKS << prc
64
8
  end
@@ -64,13 +64,13 @@ module GirFFI
64
64
  # Wrap the passed pointer in an instance of the current class. Will not
65
65
  # do any casting to subtypes.
66
66
  def direct_wrap ptr
67
- return nil if ptr.nil? or ptr.null?
67
+ return nil if !ptr or ptr.null?
68
68
  obj = _real_new
69
69
  obj.instance_variable_set :@struct, self::Struct.new(ptr.to_ptr)
70
70
  obj
71
71
  end
72
72
 
73
- def allocate
73
+ def _allocate
74
74
  obj = _real_new
75
75
  obj.instance_variable_set :@struct, self::Struct.new
76
76
  obj
@@ -2,12 +2,11 @@ module GirFFI
2
2
  # The InOutPointer class handles conversion between ruby types and
3
3
  # pointers for arguments with direction :inout and :out.
4
4
  class InOutPointer < FFI::Pointer
5
- attr_reader :value_type, :sub_type
5
+ attr_reader :value_type
6
6
 
7
- def initialize value, type, sub_type=nil
7
+ def initialize value, type
8
8
  @ffi_type = TypeMap.map_basic_type_or_string type
9
9
  @value_type = type
10
- @sub_type = sub_type
11
10
 
12
11
  value = adjust_value_in value
13
12
 
@@ -24,34 +23,15 @@ module GirFFI
24
23
  adjust_value_out value
25
24
  end
26
25
 
27
- def to_sized_array_value size
28
- # FIXME: Simulated Polymorphism.
29
- raise "Not allowed" if @ffi_type != :pointer or @sub_type.nil?
30
- block = self.read_pointer
31
- return nil if block.null?
32
- ArgHelper.ptr_to_typed_array @sub_type, block, size
33
- end
34
-
35
- def self.for type, sub_type=nil
26
+ def self.for type
36
27
  if Array === type
37
28
  return self.new nil, *type
38
29
  end
39
- self.new nil, type, sub_type
30
+ self.new nil, type
40
31
  end
41
32
 
42
- def self.from type, value, sub_type=nil
43
- if Array === type
44
- _, sub_t = *type
45
- # TODO: Take array type into account (zero-terminated or not)
46
- return self.from_array sub_t, value
47
- end
48
- self.new value, type, sub_type
49
- end
50
-
51
- def self.from_array type, array
52
- return nil if array.nil?
53
- ptr = InPointer.from_array(type, array)
54
- self.from :pointer, ptr, type
33
+ def self.from type, value
34
+ self.new value, type
55
35
  end
56
36
 
57
37
  private
@@ -60,6 +40,7 @@ module GirFFI
60
40
  case @value_type
61
41
  when :gboolean
62
42
  (value ? 1 : 0)
43
+ # TODO: Remove all references to :utf8 from this class
63
44
  when :utf8
64
45
  InPointer.from :utf8, value
65
46
  else
@@ -75,8 +56,6 @@ module GirFFI
75
56
  case @value_type
76
57
  when :gboolean
77
58
  (value != 0)
78
- when :utf8
79
- ArgHelper.ptr_to_utf8 value
80
59
  else
81
60
  value
82
61
  end
@@ -4,30 +4,22 @@ module GirFFI
4
4
  # arrays, strings, or interfaces.
5
5
  class InPointer < FFI::Pointer
6
6
  def self.from_array type, ary
7
- return nil if ary.nil?
7
+ return if !ary
8
8
  case type
9
9
  when :utf8, :filename
10
10
  from_utf8_array ary
11
- when :interface_pointer
12
- from_interface_pointer_array ary
13
11
  when Symbol
14
12
  from_basic_type_array type, ary
15
13
  when FFI::Enum
16
14
  from_enum_array type, ary
17
- when Array
18
- from_interface_pointer_array ary
19
15
  else
20
16
  raise NotImplementedError, type
21
17
  end
22
18
  end
23
19
 
24
20
  def self.from type, val
25
- return nil if val.nil?
21
+ return if !val
26
22
  case type
27
- when Array
28
- _, sub_t = *type
29
- # TODO: Take array type into account (zero-terminated or not)
30
- self.from_array sub_t, val
31
23
  when :utf8, :filename
32
24
  from_utf8 val
33
25
  when :gint32, :gint8
@@ -44,38 +36,39 @@ module GirFFI
44
36
  private
45
37
 
46
38
  def from_utf8_array ary
47
- ptr_ary = ary.map {|str| self.from :utf8, str}
39
+ ptr_ary = ary.map {|str| from_utf8 str}
48
40
  ptr_ary << nil
49
- self.from_array :pointer, ptr_ary
41
+ from_basic_type_array :pointer, ptr_ary
50
42
  end
51
43
 
52
44
  def from_interface_pointer_array ary
53
45
  ptr_ary = ary.map {|ifc| ifc.to_ptr}
54
46
  ptr_ary << nil
55
- self.from_array :pointer, ptr_ary
47
+ from_basic_type_array :pointer, ptr_ary
56
48
  end
57
49
 
58
50
  def from_enum_array type, ary
59
- self.from_array :int32, ary.map {|sym| type.to_native sym, nil }
51
+ from_basic_type_array :int32, ary.map {|sym| type.to_native sym, nil }
60
52
  end
61
53
 
62
54
  def from_utf8 str
63
55
  len = str.bytesize
64
56
  ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
65
- self.new ptr
57
+ new ptr
66
58
  end
67
59
 
68
60
  def from_basic_type_array type, ary
69
61
  ffi_type = TypeMap.map_basic_type type
70
- block = ArgHelper.allocate_array_of_type ffi_type, ary.length + 1
62
+ length = ary.length
63
+
64
+ block = ArgHelper.allocate_array_of_type ffi_type, length + 1
71
65
  block.send "put_array_of_#{ffi_type}", 0, ary
72
66
  block.send("put_#{ffi_type}",
73
- ary.length * FFI.type_size(ffi_type),
67
+ length * FFI.type_size(ffi_type),
74
68
  (ffi_type == :pointer ? nil : 0))
75
69
 
76
- self.new block
70
+ new block
77
71
  end
78
-
79
72
  end
80
73
  end
81
74
  end
@@ -19,6 +19,11 @@ module GirFFI
19
19
  arg
20
20
  end
21
21
  end
22
+
23
+ def to_ffitype
24
+ return :pointer if direction != :in
25
+ return argument_type.to_ffitype
26
+ end
22
27
  end
23
28
  end
24
29
  end
@@ -0,0 +1,16 @@
1
+ module GirFFI
2
+ module InfoExt
3
+ # Extensions for GObjectIntrospection::ICallableInfo needed by GirFFI
4
+ module ICallableInfo
5
+ def argument_ffi_types
6
+ args.map { |arg| arg.to_ffitype }
7
+ end
8
+
9
+ def return_ffi_type
10
+ return_type.to_ffitype
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ GObjectIntrospection::ICallableInfo.send :include, GirFFI::InfoExt::ICallableInfo
@@ -0,0 +1,15 @@
1
+ module GirFFI
2
+ module InfoExt
3
+ # Extensions for GObjectIntrospection::IFunctionInfo needed by GirFFI
4
+ module IFunctionInfo
5
+ def argument_ffi_types
6
+ super.tap do |types|
7
+ types.unshift :pointer if method?
8
+ types << :pointer if throws?
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ GObjectIntrospection::IFunctionInfo.send :include, GirFFI::InfoExt::IFunctionInfo