gir_ffi 0.5.2 → 0.6.0

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