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.
- data/History.txt +5 -0
- data/lib/ffi-glib/array.rb +2 -3
- data/lib/ffi-glib/container_class_methods.rb +3 -4
- data/lib/ffi-glib/hash_table.rb +7 -3
- data/lib/ffi-glib/list_methods.rb +1 -1
- data/lib/ffi-glib/sized_array.rb +66 -0
- data/lib/ffi-glib/strv.rb +1 -1
- data/lib/ffi-glib.rb +5 -4
- data/lib/ffi-gobject/object.rb +2 -3
- data/lib/ffi-gobject/ruby_closure.rb +3 -2
- data/lib/ffi-gobject/value.rb +26 -14
- data/lib/ffi-gobject.rb +8 -5
- data/lib/ffi-gobject_introspection/g_error.rb +1 -0
- data/lib/ffi-gobject_introspection/i_base_info.rb +3 -2
- data/lib/ffi-gobject_introspection/i_union_info.rb +21 -8
- data/lib/ffi-gobject_introspection/lib.rb +1 -0
- data/lib/gir_ffi/argument_builder.rb +8 -20
- data/lib/gir_ffi/base_argument_builder.rb +13 -30
- data/lib/gir_ffi/builder/module.rb +3 -9
- data/lib/gir_ffi/builder/type/base.rb +2 -0
- data/lib/gir_ffi/builder/type/callback.rb +2 -2
- data/lib/gir_ffi/builder/type/enum.rb +1 -0
- data/lib/gir_ffi/builder/type/object.rb +13 -3
- data/lib/gir_ffi/builder/type/registered_type.rb +1 -1
- data/lib/gir_ffi/builder/type/struct.rb +18 -3
- data/lib/gir_ffi/builder/type/unintrospectable.rb +5 -45
- data/lib/gir_ffi/builder/type/user_defined.rb +3 -15
- data/lib/gir_ffi/builder/type.rb +5 -5
- data/lib/gir_ffi/builder.rb +5 -80
- data/lib/gir_ffi/callback.rb +65 -2
- data/lib/gir_ffi/callback_helper.rb +0 -56
- data/lib/gir_ffi/class_base.rb +2 -2
- data/lib/gir_ffi/in_out_pointer.rb +7 -28
- data/lib/gir_ffi/in_pointer.rb +12 -19
- data/lib/gir_ffi/info_ext/i_arg_info.rb +5 -0
- data/lib/gir_ffi/info_ext/i_callable_info.rb +16 -0
- data/lib/gir_ffi/info_ext/i_function_info.rb +15 -0
- data/lib/gir_ffi/info_ext/i_signal_info.rb +17 -10
- data/lib/gir_ffi/info_ext/i_type_info.rb +63 -39
- data/lib/gir_ffi/info_ext.rb +5 -3
- data/lib/gir_ffi/null_argument_builder.rb +1 -1
- data/lib/gir_ffi/return_value_builder.rb +24 -16
- data/lib/gir_ffi/unintrospectable_type_info.rb +41 -0
- data/lib/gir_ffi/user_defined_property_info.rb +15 -0
- data/lib/gir_ffi/user_defined_type_info.rb +25 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/lib/gir_ffi-base.rb +3 -0
- data/lib/gir_ffi.rb +2 -1
- data/test/ffi-glib/sized_array_test.rb +87 -0
- data/test/ffi-gobject_introspection/i_base_info_test.rb +4 -5
- data/test/gir_ffi/argument_builder_test.rb +26 -55
- data/test/gir_ffi/builder/type/unintrospectable_test.rb +3 -19
- data/test/gir_ffi/builder/type/user_defined_test.rb +16 -21
- data/test/gir_ffi/builder_test.rb +31 -53
- data/test/gir_ffi/callback_helper_test.rb +0 -47
- data/test/gir_ffi/callback_test.rb +49 -0
- data/test/gir_ffi/function_builder_test.rb +8 -8
- data/test/gir_ffi/in_out_pointer_test.rb +2 -53
- data/test/gir_ffi/in_pointer_test.rb +0 -13
- data/test/gir_ffi/info_ext/i_callable_info_test.rb +32 -0
- data/test/gir_ffi/info_ext/i_function_info_test.rb +61 -0
- data/test/gir_ffi/info_ext/i_signal_info_test.rb +7 -0
- data/test/gir_ffi/info_ext/i_type_info_test.rb +158 -77
- data/test/gir_ffi/return_value_builder_test.rb +2 -2
- data/test/gir_ffi/unintrospectable_type_info_test.rb +95 -0
- data/test/gir_ffi/user_defined_property_info_test.rb +19 -0
- data/test/gir_ffi/user_defined_type_info_test.rb +34 -0
- data/test/integration/generated_gimarshallingtests_test.rb +10 -10
- data/test/integration/generated_regress_test.rb +10 -10
- metadata +24 -15
- data/lib/gir_ffi/builder/type/struct_based.rb +0 -31
- data/lib/gir_ffi/user_defined/i_base_info.rb +0 -7
- data/lib/gir_ffi/user_defined/i_object_info.rb +0 -13
- data/lib/gir_ffi/user_defined/i_property_info.rb +0 -9
- data/lib/gir_ffi/user_defined/i_registered_type_info.rb +0 -10
- data/test/gir_ffi/user_defined/i_object_info_test.rb +0 -18
- data/test/gir_ffi/user_defined/i_property_info_test.rb +0 -14
- data/test/gir_ffi/user_defined/i_registered_type_info_test.rb +0 -10
@@ -1,16 +1,31 @@
|
|
1
|
-
require 'gir_ffi/builder/type/
|
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 <
|
10
|
+
class Struct < RegisteredType
|
11
|
+
include WithMethods
|
12
|
+
include WithLayout
|
13
|
+
|
8
14
|
private
|
9
15
|
|
10
16
|
def setup_class
|
11
|
-
|
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
|
-
|
18
|
-
|
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
|
-
|
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
|
12
|
-
@
|
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 = @
|
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
|
data/lib/gir_ffi/builder/type.rb
CHANGED
@@ -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/
|
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/
|
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
|
data/lib/gir_ffi/builder.rb
CHANGED
@@ -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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
data/lib/gir_ffi/callback.rb
CHANGED
@@ -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
|
-
|
5
|
-
|
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
|
data/lib/gir_ffi/class_base.rb
CHANGED
@@ -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
|
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
|
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
|
5
|
+
attr_reader :value_type
|
6
6
|
|
7
|
-
def initialize value, type
|
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
|
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
|
30
|
+
self.new nil, type
|
40
31
|
end
|
41
32
|
|
42
|
-
def self.from type, value
|
43
|
-
|
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
|
data/lib/gir_ffi/in_pointer.rb
CHANGED
@@ -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
|
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
|
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|
|
39
|
+
ptr_ary = ary.map {|str| from_utf8 str}
|
48
40
|
ptr_ary << nil
|
49
|
-
|
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
|
-
|
47
|
+
from_basic_type_array :pointer, ptr_ary
|
56
48
|
end
|
57
49
|
|
58
50
|
def from_enum_array type, ary
|
59
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
67
|
+
length * FFI.type_size(ffi_type),
|
74
68
|
(ffi_type == :pointer ? nil : 0))
|
75
69
|
|
76
|
-
|
70
|
+
new block
|
77
71
|
end
|
78
|
-
|
79
72
|
end
|
80
73
|
end
|
81
74
|
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
|