gir_ffi 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.2.1 / 2011-11-20
2
+
3
+ * Fix handling of output parameters that are arrays of pointers to
4
+ structures (i.e., of type Foo***).
5
+
1
6
  == 0.2.0 / 2011-11-19
2
7
 
3
8
  * Add support for properties, with #get_property and #set_property.
@@ -23,34 +23,12 @@ module GirFFI
23
23
  FFI::Pointer.new(obj.object_id)
24
24
  end
25
25
 
26
- # Converts an outptr to a string array.
27
- def self.outptr_to_utf8_array ptr, size
28
- block = ptr.read_pointer
29
- return nil if block.null?
30
- ptr_to_utf8_array block, size
31
- end
32
-
33
- # Converts an outptr to an array of int.
34
- def self.outptr_to_int32_array ptr, size
35
- block = ptr.read_pointer
36
- return nil if block.null?
37
- ptr_to_gint32_array block, size
38
- end
39
-
40
- # Converts an outptr to an array of the given class.
41
- def self.outptr_to_interface_array klass, ptr, size
42
- block = ptr.read_pointer
43
- return nil if block.null?
44
- ptr_to_interface_array klass, block, size
45
- end
46
-
47
- class << self
48
- alias outptr_to_int_array outptr_to_int32_array
49
- alias outptr_to_gint32_array outptr_to_int32_array
50
- end
51
-
52
26
  def self.ptr_to_typed_array type, ptr, size
53
- if type == :utf8
27
+ if type.is_a? Class
28
+ ptr_to_interface_array type, ptr, size
29
+ elsif type.is_a? Array
30
+ ptr_to_interface_pointer_array type[1], ptr, size
31
+ elsif type == :utf8
54
32
  ptr_to_utf8_array ptr, size
55
33
  else
56
34
  ffi_type = TypeMap.map_basic_type type
@@ -84,6 +62,13 @@ module GirFFI
84
62
  end
85
63
  end
86
64
 
65
+ def self.ptr_to_interface_pointer_array klass, ptr, size
66
+ ptrs = ptr.read_array_of_pointer(size)
67
+ ptrs.map do |optr|
68
+ klass.wrap(optr)
69
+ end
70
+ end
71
+
87
72
  if RUBY_VERSION < "1.9"
88
73
  def self.ptr_to_utf8 ptr
89
74
  ptr.null? ? nil : ptr.read_string
@@ -56,12 +56,24 @@ module GirFFI
56
56
 
57
57
  def argument_class_name
58
58
  iface = type_info.interface
59
+ # FIXME: Extract to ITypeInfo.
59
60
  "::#{iface.safe_namespace}::#{iface.name}"
60
61
  end
61
62
 
62
- def subtype_class_name index=0
63
- iface = type_info.param_type(index).interface
64
- "::#{iface.safe_namespace}::#{iface.name}"
63
+ def subtype_tag_or_class_name index=0
64
+ type = type_info.param_type(index)
65
+ tag = type.tag
66
+ base = if tag == :interface
67
+ iface = type.interface
68
+ "::#{iface.safe_namespace}::#{iface.name}"
69
+ else
70
+ tag.inspect
71
+ end
72
+ if type.pointer?
73
+ "[:pointer, #{base}]"
74
+ else
75
+ base
76
+ end
65
77
  end
66
78
 
67
79
  def array_size
@@ -238,15 +238,12 @@ module GirFFI::Builder
238
238
  # Implements argument processing for array arguments with direction
239
239
  # :out.
240
240
  class CArrayOutArgument < PointerLikeOutArgument
241
- def postpost
242
- tag = subtype_tag
243
-
244
- args = [callarg, array_size]
245
- if tag == :interface or tag == :interface_pointer
246
- args.unshift subtype_class_name
247
- end
241
+ def pre
242
+ [ "#{callarg} = GirFFI::InOutPointer.for_array #{subtype_tag_or_class_name}" ]
243
+ end
248
244
 
249
- [ "#{retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{args.join ', '}" ]
245
+ def postpost
246
+ [ "#{retname} = #{callarg}.to_sized_array_value #{array_size}" ]
250
247
  end
251
248
  end
252
249
 
@@ -384,9 +381,8 @@ module GirFFI::Builder
384
381
  end
385
382
 
386
383
  def postpost
387
- tag = subtype_tag
388
384
  size = array_size
389
- pst = [ "#{retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{callarg}, #{size}" ]
385
+ pst = [ "#{retname} = #{callarg}.to_sized_array_value #{size}" ]
390
386
  pst
391
387
  end
392
388
 
@@ -2,6 +2,8 @@ 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
6
+
5
7
  def initialize ptr, type, ffi_type, sub_type=nil
6
8
  super ptr
7
9
  @ffi_type = ffi_type
@@ -37,11 +39,11 @@ module GirFFI
37
39
  end
38
40
  end
39
41
 
40
- def self.for type
42
+ def self.for type, sub_type=nil
41
43
  ffi_type = TypeMap.map_basic_type_or_string type
42
44
  ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
43
45
  ptr.send "put_#{ffi_type}", 0, nil_value_for(type)
44
- self.new ptr, type, ffi_type
46
+ self.new ptr, type, ffi_type, sub_type
45
47
  end
46
48
 
47
49
  def self.from type, value, sub_type=nil
@@ -58,6 +60,10 @@ module GirFFI
58
60
  self.from :pointer, ptr, type
59
61
  end
60
62
 
63
+ def self.for_array type
64
+ self.for :pointer, type
65
+ end
66
+
61
67
  class << self
62
68
  def adjust_value_in type, value
63
69
  case type
@@ -1,4 +1,4 @@
1
1
  module GirFFI
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
4
4
 
@@ -1,52 +1,6 @@
1
1
  require File.expand_path('gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  class ArgHelperTest < MiniTest::Spec
4
- context "The outptr_to_utf8_array method" do
5
- context "when called with a valid pointer to a string array" do
6
- setup do
7
- p = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:pointer) * 2
8
- p.write_array_of_pointer ["one", "two"].map {|str|
9
- len = str.bytesize
10
- GirFFI::AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
11
- }
12
- @ptr = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:pointer)
13
- @ptr.write_pointer p
14
- end
15
-
16
- should "return the string array" do
17
- assert_equal ["one", "two"],
18
- GirFFI::ArgHelper.outptr_to_utf8_array(@ptr, 2)
19
- end
20
- end
21
-
22
- context "when called with a pointer to a string array containing a null pointer" do
23
- setup do
24
- ptrs = ["one", "two"].map {|str|
25
- len = str.bytesize
26
- GirFFI::AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
27
- }
28
- ptrs << nil
29
- p = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:pointer) * 3
30
- p.write_array_of_pointer ptrs
31
- @ptr = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:pointer)
32
- @ptr.write_pointer p
33
- end
34
-
35
- should "render the null pointer as nil" do
36
- assert_equal ["one", "two", nil],
37
- GirFFI::ArgHelper.outptr_to_utf8_array(@ptr, 3)
38
- end
39
- end
40
-
41
- context "when called with a pointer to null" do
42
- should "return nil" do
43
- ptr = GirFFI::InOutPointer.for :pointer
44
- assert ptr.read_pointer.null?
45
- assert_nil GirFFI::ArgHelper.outptr_to_utf8_array(ptr, 0)
46
- end
47
- end
48
- end
49
-
50
4
  context "The object_to_inptr method" do
51
5
  context "when called with an object implementing to_ptr" do
52
6
  should "return the result of to_ptr" do
@@ -14,7 +14,7 @@ class FunctionDefinitionBuilderTest < MiniTest::Spec
14
14
  _v2 = GirFFI::InOutPointer.from_array :utf8, argv
15
15
  ::Lib.gtk_init _v1, _v2
16
16
  _v3 = _v1.to_value
17
- _v4 = GirFFI::ArgHelper.outptr_to_utf8_array _v2, _v3
17
+ _v4 = _v2.to_sized_array_value _v3
18
18
  return _v4
19
19
  end
20
20
  "
@@ -96,11 +96,11 @@ class FunctionDefinitionBuilderTest < MiniTest::Spec
96
96
 
97
97
  expected =
98
98
  "def test_array_int_null_out
99
- _v1 = GirFFI::InOutPointer.for :pointer
99
+ _v1 = GirFFI::InOutPointer.for_array :gint32
100
100
  _v2 = GirFFI::InOutPointer.for :gint32
101
101
  ::Lib.regress_test_array_int_null_out _v1, _v2
102
102
  _v3 = _v2.to_value
103
- _v4 = GirFFI::ArgHelper.outptr_to_gint32_array _v1, _v3
103
+ _v4 = _v1.to_sized_array_value _v3
104
104
  return _v4
105
105
  end"
106
106
 
@@ -119,7 +119,7 @@ class FunctionDefinitionBuilderTest < MiniTest::Spec
119
119
  _v2 = GirFFI::InOutPointer.from :gint32, length
120
120
  ::Lib.gi_marshalling_tests_object_method_array_inout self, _v1, _v2
121
121
  _v3 = _v2.to_value
122
- _v4 = GirFFI::ArgHelper.outptr_to_gint32_array _v1, _v3
122
+ _v4 = _v1.to_sized_array_value _v3
123
123
  return _v4
124
124
  end"
125
125
 
@@ -560,6 +560,29 @@ class GeneratedRegressTest < MiniTest::Spec
560
560
  Regress.set_abort_on_error true
561
561
  end
562
562
 
563
+ describe "#test_array_fixed_out_objects" do
564
+ before do
565
+ @result = Regress.test_array_fixed_out_objects
566
+ end
567
+
568
+ it "returns an array of two items" do
569
+ assert_equal 2, @result.length
570
+ end
571
+
572
+ it "returns an array TestObj objects" do
573
+ @result.each {|o|
574
+ assert_instance_of Regress::TestObj, o
575
+ }
576
+ end
577
+
578
+ it "returns objects with the correct GType" do
579
+ gtype = Regress::TestObj.get_gtype
580
+ @result.each {|o|
581
+ assert_equal gtype, GObject.type_from_instance(o)
582
+ }
583
+ end
584
+ end
585
+
563
586
  describe "#test_array_fixed_size_int_in" do
564
587
  should "return the correct result" do
565
588
  assert_equal 5 + 4 + 3 + 2 + 1, Regress.test_array_fixed_size_int_in([5, 4, 3, 2, 1])
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::ArgHelper do
4
+ describe "::ptr_to_typed_array" do
5
+ describe "for pointers to class types" do
6
+ it "reads an array of pointers and wraps each in the class" do
7
+ c = Class.new do
8
+ def self.wrap a; "wrapped: #{a}"; end
9
+ end
10
+
11
+ mock(ptr = Object.new).read_array_of_pointer(2) { [:a, :b] }
12
+
13
+ result = GirFFI::ArgHelper.ptr_to_typed_array [:pointer, c], ptr, 2
14
+
15
+ assert_equal ["wrapped: a", "wrapped: b"], result
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::Builder::Argument::Base do
4
+ describe "#subtype_tag_or_class_name" do
5
+ describe "for a simple type" do
6
+ it "returns the string ':void'" do
7
+ mock(subtype = Object.new).tag { :void }
8
+ mock(subtype).pointer? { false }
9
+
10
+ mock(info = Object.new).param_type(0) { subtype }
11
+
12
+ builder = GirFFI::Builder::Argument::Base.new nil, 'foo', info, nil
13
+ assert_equal ":void", builder.subtype_tag_or_class_name
14
+ end
15
+ end
16
+
17
+ describe "for an array of simple type :foo" do
18
+ it "returns the string ':foo'" do
19
+ mock(subtype = Object.new).tag { :foo }
20
+ mock(subtype).pointer? { false }
21
+
22
+ mock(info = Object.new).param_type(0) { subtype }
23
+
24
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, nil
25
+ assert_equal ":foo", builder.subtype_tag_or_class_name
26
+ end
27
+ end
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
+
34
+ mock(subtype = Object.new).tag { :interface }
35
+ mock(subtype).interface { interface }
36
+ mock(subtype).pointer? { false }
37
+
38
+ mock(info = Object.new).param_type(0) { subtype }
39
+
40
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, nil
41
+ assert_equal "::Foo::Bar", builder.subtype_tag_or_class_name
42
+ end
43
+ end
44
+
45
+ describe "for an array of pointer to simple type :foo" do
46
+ it "returns the string '[:pointer, :foo]'" do
47
+ mock(subtype = Object.new).tag { :foo }
48
+ mock(subtype).pointer? { true }
49
+
50
+ mock(info = Object.new).param_type(0) { subtype }
51
+
52
+ builder = GirFFI::Builder::Argument::Base.new nil, 'bar', info, nil
53
+ assert_equal "[:pointer, :foo]", builder.subtype_tag_or_class_name
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+
@@ -10,6 +10,23 @@ describe GirFFI::Builder::Function do
10
10
  assert_equal "result_from_generate", builder.pretty_print
11
11
  end
12
12
  end
13
+
14
+ it "builds a correct definition of Regress:test_array_fixed_out_objects" do
15
+ go = get_introspection_data 'Regress', 'test_array_fixed_out_objects'
16
+ fbuilder = GirFFI::Builder::Function.new go, Lib
17
+ code = fbuilder.generate
18
+
19
+ expected =
20
+ "def test_array_fixed_out_objects
21
+ _v1 = GirFFI::InOutPointer.for_array [:pointer, ::Regress::TestObj]
22
+ ::Lib.regress_test_array_fixed_out_objects _v1
23
+ _v2 = _v1.to_sized_array_value 2
24
+ return _v2
25
+ end"
26
+
27
+ assert_equal cws(expected), cws(code)
28
+ end
29
+
13
30
  end
14
31
 
15
32
 
@@ -80,7 +80,7 @@ describe GirFFI::InOutPointer do
80
80
  end
81
81
  end
82
82
 
83
- describe ".for" do
83
+ describe "::for" do
84
84
  it "handles :gboolean" do
85
85
  GirFFI::InOutPointer.for :gboolean
86
86
  end
@@ -90,6 +90,26 @@ describe GirFFI::InOutPointer do
90
90
  end
91
91
  end
92
92
 
93
+ describe "::for_array" do
94
+ it "handles :gint32" do
95
+ @ptr = GirFFI::InOutPointer.for_array :gint32
96
+ assert_equal :pointer, @ptr.value_type
97
+ assert_equal :gint32, @ptr.sub_type
98
+ end
99
+
100
+ it "handles GObject" do
101
+ @ptr = GirFFI::InOutPointer.for_array GObject::Object
102
+ assert_equal :pointer, @ptr.value_type
103
+ assert_equal GObject::Object, @ptr.sub_type
104
+ end
105
+
106
+ it "handles pointer to GObject" do
107
+ @ptr = GirFFI::InOutPointer.for_array [:pointer, GObject::Object]
108
+ assert_equal :pointer, @ptr.value_type
109
+ assert_equal [:pointer, GObject::Object], @ptr.sub_type
110
+ end
111
+ end
112
+
93
113
  describe "#to_value" do
94
114
  it "returns the held value" do
95
115
  ptr = GirFFI::InOutPointer.from :gint32, 123
@@ -114,16 +134,17 @@ describe GirFFI::InOutPointer do
114
134
  assert_equal "Some value", ptr.to_value
115
135
  end
116
136
  end
137
+ end
117
138
 
139
+ describe "#to_sized_array_value" do
118
140
  describe "for an array of :gint32" do
119
141
  before do
120
- @result = GirFFI::InOutPointer.from_array :gint32, [1, 2, 3]
142
+ @ptr = GirFFI::InOutPointer.from_array :gint32, [1, 2, 3]
121
143
  end
122
144
 
123
145
  it "returns an array of integers with the correct values" do
124
- assert_equal [1, 2, 3], @result.to_sized_array_value(3)
146
+ assert_equal [1, 2, 3], @ptr.to_sized_array_value(3)
125
147
  end
126
148
  end
127
-
128
149
  end
129
150
  end
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.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-19 00:00:00.000000000 Z
12
+ date: 2011-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- requirement: &13966040 !ruby/object:Gem::Requirement
16
+ requirement: &12290620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.8
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *13966040
24
+ version_requirements: *12290620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: indentation
27
- requirement: &13964120 !ruby/object:Gem::Requirement
27
+ requirement: &12289700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.0.6
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *13964120
35
+ version_requirements: *12289700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitest
38
- requirement: &13975240 !ruby/object:Gem::Requirement
38
+ requirement: &12288300 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.0.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *13975240
46
+ version_requirements: *12288300
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rr
49
- requirement: &13973360 !ruby/object:Gem::Requirement
49
+ requirement: &12285900 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.2
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *13973360
57
+ version_requirements: *12285900
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &13987300 !ruby/object:Gem::Requirement
60
+ requirement: &12284940 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 0.9.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *13987300
68
+ version_requirements: *12284940
69
69
  description:
70
70
  email:
71
71
  - matijs@matijs.net
@@ -175,7 +175,9 @@ files:
175
175
  - test/girffi_test.rb
176
176
  - test/interface_type_builder_test.rb
177
177
  - test/unit/union_builder_test.rb
178
+ - test/unit/argument_builder_test.rb
178
179
  - test/unit/callback_builder_test.rb
180
+ - test/unit/arg_helper_test.rb
179
181
  - test/unit/constant_builder_test.rb
180
182
  - test/unit/function_builder_test.rb
181
183
  - test/unit/module_builder_test.rb
@@ -292,6 +294,8 @@ test_files:
292
294
  - test/test_helper.rb
293
295
  - test/type_builder_test.rb
294
296
  - test/unintrospectable_type_builder_test.rb
297
+ - test/unit/arg_helper_test.rb
298
+ - test/unit/argument_builder_test.rb
295
299
  - test/unit/builder_test.rb
296
300
  - test/unit/callback_builder_test.rb
297
301
  - test/unit/callback_helper_test.rb