gir_ffi 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/lib/ffi-glib.rb +1 -0
- data/lib/ffi-glib/array.rb +49 -10
- data/lib/ffi-glib/hash_table.rb +19 -5
- data/lib/ffi-glib/list.rb +4 -1
- data/lib/ffi-glib/list_methods.rb +8 -1
- data/lib/ffi-glib/s_list.rb +4 -1
- data/lib/ffi-glib/strv.rb +31 -0
- data/lib/ffi-gobject.rb +2 -35
- data/lib/ffi-gobject/base.rb +38 -0
- data/lib/ffi-gobject/object.rb +28 -30
- data/lib/ffi-gobject/value.rb +72 -56
- data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -1
- data/lib/ffi-gobject_introspection/lib.rb +3 -1
- data/lib/gir_ffi/arg_helper.rb +2 -19
- data/lib/gir_ffi/builder/argument.rb +239 -305
- data/lib/gir_ffi/builder/argument/base.rb +12 -9
- data/lib/gir_ffi/builder/argument/in_base.rb +2 -6
- data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
- data/lib/gir_ffi/builder/argument/out_base.rb +0 -11
- data/lib/gir_ffi/builder/field.rb +55 -0
- data/lib/gir_ffi/builder/function.rb +7 -7
- data/lib/gir_ffi/builder/module.rb +5 -7
- data/lib/gir_ffi/builder/type/object.rb +0 -33
- data/lib/gir_ffi/builder/type/registered_type.rb +0 -16
- data/lib/gir_ffi/builder/type/struct_based.rb +3 -3
- data/lib/gir_ffi/builder/type/unintrospectable.rb +1 -1
- data/lib/gir_ffi/builder/type/with_layout.rb +26 -58
- data/lib/gir_ffi/builder/type/with_methods.rb +9 -11
- data/lib/gir_ffi/class_base.rb +24 -6
- data/lib/gir_ffi/ffi_ext/pointer.rb +15 -0
- data/lib/gir_ffi/in_pointer.rb +10 -5
- data/lib/gir_ffi/info_ext/i_field_info.rb +15 -0
- data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
- data/lib/gir_ffi/method_stubber.rb +18 -0
- data/lib/gir_ffi/type_map.rb +1 -0
- data/lib/gir_ffi/variable_name_generator.rb +2 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/builder_test.rb +6 -5
- data/test/ffi-glib/array_test.rb +40 -5
- data/test/ffi-glib/hash_table_test.rb +27 -3
- data/test/ffi-glib/list_test.rb +23 -0
- data/test/ffi-glib/strv_test.rb +41 -0
- data/test/ffi-gobject/gobject_test.rb +26 -22
- data/test/ffi-gobject/value_test.rb +26 -1
- data/test/ffi-gobject_introspection/lib_test.rb +10 -0
- data/test/gir_ffi_test_helper.rb +1 -1
- data/test/integration/derived_classes_test.rb +31 -0
- data/test/integration/generated_gimarshallingtests_test.rb +29 -15
- data/test/integration/generated_gio_test.rb +5 -6
- data/test/integration/generated_regress_test.rb +11 -7
- data/test/integration/method_lookup_test.rb +32 -0
- data/test/interface_type_builder_test.rb +1 -1
- data/test/test_helper.rb +38 -0
- data/test/unit/argument_builder_test.rb +16 -4
- data/test/unit/class_base_test.rb +48 -0
- data/test/unit/function_builder_test.rb +144 -4
- data/test/unit/hash_table_element_type_provider_test.rb +16 -0
- data/test/unit/i_field_info_test.rb +39 -0
- data/test/unit/i_type_info_test.rb +23 -0
- data/test/unit/list_element_type_provider_test.rb +13 -0
- data/test/unit/module_builder_test.rb +1 -1
- data/test/unit/object_type_builder_test.rb +0 -17
- data/test/unit/struct_builder_test.rb +27 -39
- metadata +118 -60
- data/lib/gir_ffi/builder/argument/hash_table_base.rb +0 -20
- data/lib/gir_ffi/builder/argument/list_base.rb +0 -16
- data/test/class_base_test.rb +0 -10
- data/test/function_definition_builder_test.rb +0 -130
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'gir_ffi/method_stubber'
|
2
|
+
|
1
3
|
module GirFFI
|
2
4
|
module Builder
|
3
5
|
module Type
|
@@ -15,6 +17,10 @@ module GirFFI
|
|
15
17
|
attach_and_define_method method, go, build_class
|
16
18
|
end
|
17
19
|
|
20
|
+
def has_instance_method method
|
21
|
+
!!instance_method_introspection_data(method)
|
22
|
+
end
|
23
|
+
|
18
24
|
private
|
19
25
|
|
20
26
|
def meta_class
|
@@ -28,7 +34,7 @@ module GirFFI
|
|
28
34
|
|
29
35
|
def instance_method_introspection_data method
|
30
36
|
data = method_introspection_data method
|
31
|
-
return
|
37
|
+
return data if data && data.method?
|
32
38
|
end
|
33
39
|
|
34
40
|
def function_definition_builder go
|
@@ -43,24 +49,16 @@ module GirFFI
|
|
43
49
|
return false if go.nil?
|
44
50
|
Builder.attach_ffi_function lib, go
|
45
51
|
modul.class_eval { remove_method method }
|
46
|
-
|
52
|
+
build_class.class_eval function_definition(go)
|
47
53
|
true
|
48
54
|
end
|
49
55
|
|
50
56
|
def stub_methods
|
51
57
|
info.get_methods.each do |minfo|
|
52
|
-
@klass.class_eval
|
58
|
+
@klass.class_eval MethodStubber.new(minfo).method_stub
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
56
|
-
def method_stub symbol, is_instance_method
|
57
|
-
"
|
58
|
-
def #{is_instance_method ? '' : 'self.'}#{symbol} *args, &block
|
59
|
-
setup_and_call :#{symbol}, *args, &block
|
60
|
-
end
|
61
|
-
"
|
62
|
-
end
|
63
|
-
|
64
62
|
def pretty_print_methods
|
65
63
|
info.get_methods.map do |minfo|
|
66
64
|
function_definition_builder(minfo).pretty_print.indent + "\n"
|
data/lib/gir_ffi/class_base.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'forwardable'
|
2
|
+
require 'gir_ffi/ffi_ext/pointer'
|
3
|
+
|
2
4
|
module GirFFI
|
3
5
|
# Base class for all generated classes. Contains code for dealing with
|
4
6
|
# the generated Struct classes.
|
@@ -20,16 +22,28 @@ module GirFFI
|
|
20
22
|
end
|
21
23
|
|
22
24
|
def setup_and_call method, *arguments, &block
|
23
|
-
|
25
|
+
result = self.class.ancestors.any? do |klass|
|
26
|
+
klass.respond_to?(:_setup_instance_method) &&
|
27
|
+
klass._setup_instance_method(method.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
unless result
|
24
31
|
raise RuntimeError, "Unable to set up instance method #{method} in #{self}"
|
25
32
|
end
|
33
|
+
|
26
34
|
self.send method, *arguments, &block
|
27
35
|
end
|
28
36
|
|
29
37
|
def self.setup_and_call method, *arguments, &block
|
30
|
-
|
38
|
+
result = self.ancestors.any? do |klass|
|
39
|
+
klass.respond_to?(:_setup_method) &&
|
40
|
+
klass._setup_method(method.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
unless result
|
31
44
|
raise RuntimeError, "Unable to set up method #{method} in #{self}"
|
32
45
|
end
|
46
|
+
|
33
47
|
self.send method, *arguments, &block
|
34
48
|
end
|
35
49
|
|
@@ -67,10 +81,7 @@ module GirFFI
|
|
67
81
|
|
68
82
|
def wrap ptr
|
69
83
|
return nil if ptr.nil? or ptr.null?
|
70
|
-
|
71
|
-
ptr = ptr.to_ptr
|
72
|
-
end
|
73
|
-
_real_new ptr
|
84
|
+
_real_new ptr.to_ptr
|
74
85
|
end
|
75
86
|
|
76
87
|
# TODO: Only makes sense for :objects.
|
@@ -81,6 +92,13 @@ module GirFFI
|
|
81
92
|
def allocate
|
82
93
|
_real_new
|
83
94
|
end
|
95
|
+
|
96
|
+
# Pass-through casting method. This may become a type checking
|
97
|
+
# method. It is overridden by GValue to implement wrapping of plain
|
98
|
+
# Ruby objects.
|
99
|
+
def from val
|
100
|
+
val
|
101
|
+
end
|
84
102
|
end
|
85
103
|
end
|
86
104
|
end
|
data/lib/gir_ffi/in_pointer.rb
CHANGED
@@ -8,11 +8,7 @@ module GirFFI
|
|
8
8
|
return from_utf8_array ary if type == :utf8
|
9
9
|
return from_interface_pointer_array ary if type == :interface_pointer
|
10
10
|
|
11
|
-
|
12
|
-
block = ArgHelper.allocate_array_of_type ffi_type, ary.length
|
13
|
-
block.send "put_array_of_#{ffi_type}", 0, ary
|
14
|
-
|
15
|
-
self.new block
|
11
|
+
return from_basic_type_array type, ary
|
16
12
|
end
|
17
13
|
|
18
14
|
def self.from type, val
|
@@ -48,6 +44,15 @@ module GirFFI
|
|
48
44
|
ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
|
49
45
|
self.new ptr
|
50
46
|
end
|
47
|
+
|
48
|
+
def from_basic_type_array type, ary
|
49
|
+
ffi_type = TypeMap.map_basic_type type
|
50
|
+
block = ArgHelper.allocate_array_of_type ffi_type, ary.length
|
51
|
+
block.send "put_array_of_#{ffi_type}", 0, ary
|
52
|
+
|
53
|
+
self.new block
|
54
|
+
end
|
55
|
+
|
51
56
|
end
|
52
57
|
end
|
53
58
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'gir_ffi/info_ext/i_type_info'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
module InfoExt
|
5
|
+
module IFieldInfo
|
6
|
+
def layout_specification
|
7
|
+
[ name.to_sym,
|
8
|
+
field_type.layout_specification_type,
|
9
|
+
offset ]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
GObjectIntrospection::IFieldInfo.send :include, GirFFI::InfoExt::IFieldInfo
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'gir_ffi/builder_helper'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
module InfoExt
|
5
|
+
module ITypeInfo
|
6
|
+
include BuilderHelper
|
7
|
+
|
8
|
+
def layout_specification_type
|
9
|
+
ffitype = GirFFI::Builder.itypeinfo_to_ffitype self
|
10
|
+
case ffitype
|
11
|
+
when Class
|
12
|
+
ffitype.const_get :Struct
|
13
|
+
when :bool
|
14
|
+
:int
|
15
|
+
when :array
|
16
|
+
subtype = param_type(0).layout_specification_type
|
17
|
+
[subtype, array_fixed_size]
|
18
|
+
else
|
19
|
+
ffitype
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
GObjectIntrospection::ITypeInfo.send :include, GirFFI::InfoExt::ITypeInfo
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Generates method stubs that will replace themselves with the real
|
3
|
+
# method upon being called.
|
4
|
+
class MethodStubber
|
5
|
+
def initialize method_info
|
6
|
+
@info = method_info
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_stub
|
10
|
+
symbol = @info.name
|
11
|
+
"
|
12
|
+
def #{@info.method? ? '' : 'self.'}#{symbol} *args, &block
|
13
|
+
setup_and_call :#{symbol}, *args, &block
|
14
|
+
end
|
15
|
+
"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/gir_ffi/type_map.rb
CHANGED
data/lib/gir_ffi/version.rb
CHANGED
data/test/builder_test.rb
CHANGED
@@ -64,7 +64,7 @@ class BuilderTest < MiniTest::Spec
|
|
64
64
|
end
|
65
65
|
|
66
66
|
should "create a Gtk::Window#to_ptr method" do
|
67
|
-
assert Gtk::Window.
|
67
|
+
assert Gtk::Window.public_method_defined? :to_ptr
|
68
68
|
end
|
69
69
|
|
70
70
|
after do
|
@@ -126,7 +126,7 @@ class BuilderTest < MiniTest::Spec
|
|
126
126
|
end
|
127
127
|
|
128
128
|
GirFFI::Builder.send :attach_ffi_function, libmod, @go
|
129
|
-
|
129
|
+
assert_defines_singleton_method libmod, :gtk_main
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -269,9 +269,10 @@ class BuilderTest < MiniTest::Spec
|
|
269
269
|
GirFFI::Builder.build_module 'Regress'
|
270
270
|
end
|
271
271
|
|
272
|
-
should "
|
273
|
-
|
274
|
-
|
272
|
+
should "autocreate singleton methods" do
|
273
|
+
refute_defines_singleton_method Regress, :test_uint
|
274
|
+
Regress.test_uint 31
|
275
|
+
assert_defines_singleton_method Regress, :test_uint
|
275
276
|
end
|
276
277
|
|
277
278
|
should "autocreate the TestObj class" do
|
data/test/ffi-glib/array_test.rb
CHANGED
@@ -32,12 +32,22 @@ describe GLib::Array do
|
|
32
32
|
|
33
33
|
assert_equal [1, 2, 3], a
|
34
34
|
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "::wrap" do
|
38
|
+
it "wraps a pointer, taking the element type as the first argument" do
|
39
|
+
arr = GLib::Array.new :gint32
|
40
|
+
arr.append_vals [1, 2, 3]
|
41
|
+
arr2 = GLib::Array.wrap :gint32, arr.to_ptr
|
42
|
+
assert_equal arr.to_a, arr2.to_a
|
43
|
+
end
|
35
44
|
|
36
|
-
it "
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
it "raises an error if the element sizes don't match" do
|
46
|
+
arr = GLib::Array.new :gint32
|
47
|
+
arr.append_vals [1, 2, 3]
|
48
|
+
assert_raises RuntimeError do
|
49
|
+
GLib::Array.wrap :gint8, arr.to_ptr
|
50
|
+
end
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
@@ -50,5 +60,30 @@ describe GLib::Array do
|
|
50
60
|
arr.append_vals [1, 2, 3]
|
51
61
|
assert_equal [1, 2, 3], arr.to_a
|
52
62
|
end
|
63
|
+
|
64
|
+
describe "::from" do
|
65
|
+
it "creates a GArray from a Ruby array" do
|
66
|
+
arr = GLib::Array.from :gint32, [3, 2, 1]
|
67
|
+
assert_equal [3, 2, 1], arr.to_a
|
68
|
+
end
|
69
|
+
|
70
|
+
it "return its argument if given a GArray" do
|
71
|
+
arr = GLib::Array.new :gint32
|
72
|
+
arr.append_vals [3, 2, 1]
|
73
|
+
arr2 = GLib::Array.from :foo, arr
|
74
|
+
assert_equal arr, arr2
|
75
|
+
end
|
76
|
+
|
77
|
+
it "wraps its argument if given a pointer" do
|
78
|
+
arr = GLib::Array.new :gint32
|
79
|
+
arr.append_vals [3, 2, 1]
|
80
|
+
pointer = arr.to_ptr
|
81
|
+
assert_instance_of FFI::Pointer, pointer
|
82
|
+
arr2 = GLib::Array.from :gint32, pointer
|
83
|
+
assert_instance_of GLib::Array, arr2
|
84
|
+
refute_equal arr, arr2
|
85
|
+
assert_equal arr.to_a, arr2.to_a
|
86
|
+
end
|
87
|
+
end
|
53
88
|
end
|
54
89
|
|
@@ -9,16 +9,40 @@ describe GLib::HashTable do
|
|
9
9
|
|
10
10
|
describe "::from_hash" do
|
11
11
|
it "creates a GHashTable from a Ruby array" do
|
12
|
-
hsh = GLib::HashTable.from_hash :utf8, :gint32,
|
12
|
+
hsh = GLib::HashTable.from_hash [:utf8, :gint32],
|
13
13
|
{"foo" => 23, "bar" => 32}
|
14
14
|
assert_equal({"foo" => 23, "bar" => 32}, hsh.to_hash)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "return its argument if given a GHashTable" do
|
18
|
-
hsh = GLib::HashTable.from_hash :utf8, :gint32, {"foo" => 23, "bar" => 32}
|
19
|
-
hsh2 = GLib::HashTable.from_hash :utf8, :gint32, hsh
|
18
|
+
hsh = GLib::HashTable.from_hash [:utf8, :gint32], {"foo" => 23, "bar" => 32}
|
19
|
+
hsh2 = GLib::HashTable.from_hash [:utf8, :gint32], hsh
|
20
20
|
assert_equal hsh, hsh2
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe "::from" do
|
25
|
+
it "creates a GHashTable from a Ruby array" do
|
26
|
+
hsh = GLib::HashTable.from [:utf8, :gint32],
|
27
|
+
{"foo" => 23, "bar" => 32}
|
28
|
+
assert_equal({"foo" => 23, "bar" => 32}, hsh.to_hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "return its argument if given a GHashTable" do
|
32
|
+
hsh = GLib::HashTable.from [:utf8, :gint32], {"foo" => 23, "bar" => 32}
|
33
|
+
hsh2 = GLib::HashTable.from [:utf8, :gint32], hsh
|
34
|
+
assert_equal hsh, hsh2
|
35
|
+
end
|
36
|
+
|
37
|
+
it "wraps its argument if given a pointer" do
|
38
|
+
hsh = GLib::HashTable.from [:utf8, :gint32], {"foo" => 23, "bar" => 32}
|
39
|
+
pointer = hsh.to_ptr
|
40
|
+
assert_instance_of FFI::Pointer, pointer
|
41
|
+
hsh2 = GLib::HashTable.from [:utf8, :gint32], pointer
|
42
|
+
assert_instance_of GLib::HashTable, hsh2
|
43
|
+
refute_equal hsh, hsh2
|
44
|
+
assert_equal hsh.to_hash, hsh2.to_hash
|
45
|
+
end
|
46
|
+
end
|
23
47
|
end
|
24
48
|
|
data/test/ffi-glib/list_test.rb
CHANGED
@@ -43,4 +43,27 @@ describe GLib::List do
|
|
43
43
|
assert_equal lst, lst2
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
describe "::from" do
|
48
|
+
it "creates a GList from a Ruby array" do
|
49
|
+
lst = GLib::List.from :gint32, [3, 2, 1]
|
50
|
+
assert_equal [3, 2, 1], lst.to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
it "return its argument if given a GList" do
|
54
|
+
lst = GLib::List.from :gint32, [3, 2, 1]
|
55
|
+
lst2 = GLib::List.from :gint32, lst
|
56
|
+
assert_equal lst, lst2
|
57
|
+
end
|
58
|
+
|
59
|
+
it "wraps its argument if given a pointer" do
|
60
|
+
lst = GLib::List.from :gint32, [3, 2, 1]
|
61
|
+
pointer = lst.to_ptr
|
62
|
+
assert_instance_of FFI::Pointer, pointer
|
63
|
+
lst2 = GLib::List.from :gint32, pointer
|
64
|
+
assert_instance_of GLib::List, lst2
|
65
|
+
refute_equal lst, lst2
|
66
|
+
assert_equal lst.to_a, lst2.to_a
|
67
|
+
end
|
68
|
+
end
|
46
69
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'ffi-glib/strv'
|
4
|
+
|
5
|
+
describe GLib::Strv do
|
6
|
+
it "wraps a pointer" do
|
7
|
+
strv = GLib::Strv.new :some_pointer
|
8
|
+
assert_equal :some_pointer, strv.to_ptr
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "::wrap" do
|
12
|
+
it "takes a pointer and returns a GLib::Strv wrapping it" do
|
13
|
+
strv = GLib::Strv.wrap :some_pointer
|
14
|
+
assert_instance_of GLib::Strv, strv
|
15
|
+
assert_equal :some_pointer, strv.to_ptr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#each" do
|
20
|
+
it "yields each string element" do
|
21
|
+
ptr = GirFFI::InPointer.from_array :utf8, ["one", "two", "three"]
|
22
|
+
strv = GLib::Strv.new ptr
|
23
|
+
arr = []
|
24
|
+
strv.each do |str|
|
25
|
+
arr << str
|
26
|
+
end
|
27
|
+
assert_equal ["one", "two", "three"], arr
|
28
|
+
end
|
29
|
+
|
30
|
+
it "yields zero times for a Strv wrapping a null pointer" do
|
31
|
+
strv = GLib::Strv.new FFI::Pointer.new(0)
|
32
|
+
strv.each do |str|
|
33
|
+
flunk
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "includes Enumerable" do
|
39
|
+
GLib::Strv.must_include Enumerable
|
40
|
+
end
|
41
|
+
end
|