gir_ffi 0.2.0 → 0.2.1

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