gir_ffi 0.6.5 → 0.6.6

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.
@@ -1,3 +1,8 @@
1
+ == 0.6.6 / 2013-08-05
2
+
3
+ * Handle GArrays of booleans and structs
4
+ * Improve handling of gbooleans
5
+
1
6
  == 0.6.5 / 2013-08-03
2
7
 
3
8
  * Handle inline arrays of structs
data/TODO.rdoc CHANGED
@@ -34,10 +34,11 @@ hidden issues.
34
34
  (11:47:15 PM) ebassi: the rest is "nice to have"
35
35
  (11:47:37 PM) ebassi: oh, and probably GBinding - but that's just because I wrote it ;-)
36
36
 
37
- == Compatibility with all implementations.
37
+ == Use FFI::DataConverter to automatically convert GObject types
38
38
 
39
- GirFFI is incompatible with Rubinius, but this is due to Rubinius' FFI
40
- implementation lagging behind the others.
39
+ GirFFI now generates loads of Something.wrap(ptr) calls; Perhaps these can be
40
+ replace by implementing to_native and from_native in ClassBase and including
41
+ FFI::DataConverter.
41
42
 
42
43
  == See Also
43
44
 
@@ -20,26 +20,41 @@ module GLib
20
20
  end
21
21
  end
22
22
 
23
- def append_vals data
24
- bytes = GirFFI::InPointer.from_array element_type, data
25
- len = data.length
23
+ def append_vals ary
24
+ bytes = GirFFI::InPointer.from_array element_type, ary
25
+ len = ary.length
26
26
  Lib.g_array_append_vals(self, bytes, len)
27
27
  self
28
28
  end
29
29
 
30
30
  # Re-implementation of the g_array_index macro
31
31
  def index idx
32
- ptr = @struct[:data].get_pointer(idx * get_element_size)
33
- # FIXME: Does not work for class-like values of element_type.
34
- GirFFI::ArgHelper.cast_from_pointer(element_type, ptr)
32
+ # TODO: Check idx < length
33
+ ptr = GirFFI::InOutPointer.new element_type, data + idx * get_element_size
34
+ case element_type
35
+ when :utf8
36
+ GirFFI::ArgHelper.ptr_to_utf8 ptr.to_value
37
+ when Symbol
38
+ ptr.to_value
39
+ else
40
+ element_type.wrap ptr.to_value
41
+ end
35
42
  end
36
43
 
37
44
  def each
38
- @struct[:len].times.each do |idx|
45
+ length.times.each do |idx|
39
46
  yield index(idx)
40
47
  end
41
48
  end
42
49
 
50
+ def length
51
+ @struct[:len]
52
+ end
53
+
54
+ def data
55
+ @struct[:data]
56
+ end
57
+
43
58
  def get_element_size
44
59
  Lib.g_array_get_element_size self
45
60
  end
@@ -66,11 +81,8 @@ module GLib
66
81
 
67
82
  def self.calculated_element_size type
68
83
  ffi_type = GirFFI::TypeMap.type_specification_to_ffitype(type)
69
- if ffi_type.is_a? Symbol
70
- FFI.type_size(ffi_type)
71
- else
72
- ffi_type.size
73
- end
84
+ # FIXME: Smell. Make struct ffi_types into DataConvertor?
85
+ FFI.type_size(ffi_type) rescue ffi_type.size
74
86
  end
75
87
 
76
88
  def calculated_element_size
@@ -104,7 +104,7 @@ module GObject
104
104
 
105
105
  def for_g_type g_type
106
106
  return nil if g_type == TYPE_NONE
107
- self.new.init g_type
107
+ self.new.tap {|it| it.init g_type }
108
108
  end
109
109
  end
110
110
 
@@ -1,5 +1,6 @@
1
1
  # This section contains code that is needed by GObjectIntrospection, but
2
2
  # belongs in modules that can only be created fully once GObjectIntrospection
3
3
  # is fully loaded.
4
+ require 'gir_ffi-base/glib/boolean'
4
5
  require 'gir_ffi-base/glib/strv'
5
6
  require 'gir_ffi-base/gobject/lib'
@@ -0,0 +1,17 @@
1
+ require 'ffi'
2
+
3
+ module GLib
4
+ # Implementation of gboolean
5
+ class Boolean
6
+ extend FFI::DataConverter
7
+ native_type :int #FFI::Type::INT
8
+
9
+ def self.from_native value, context
10
+ value != 0 ? true : false
11
+ end
12
+
13
+ def self.to_native value, context
14
+ value ? 1 : 0
15
+ end
16
+ end
17
+ end
@@ -1,12 +1,13 @@
1
1
  require 'ffi'
2
2
 
3
+ require 'gir_ffi-base'
4
+
5
+ require 'ffi-gobject_introspection'
6
+
3
7
  require 'gir_ffi/ffi_ext'
4
8
  require 'gir_ffi/class_base'
5
9
  require 'gir_ffi/type_map'
6
-
7
- require 'ffi-gobject_introspection'
8
10
  require 'gir_ffi/info_ext'
9
-
10
11
  require 'gir_ffi/in_pointer'
11
12
  require 'gir_ffi/in_out_pointer'
12
13
  require 'gir_ffi/zero_terminated'
@@ -13,18 +13,6 @@ module GirFFI
13
13
  # TODO: Move implementation here.
14
14
  ArgHelper.object_pointer_to_object self
15
15
  end
16
-
17
- # XXX: int32 is size 4, bool is size 1. Why u no crash?
18
- def put_bool offset, value
19
- int = value ? 1 : 0
20
- put_int32 offset, int
21
- end
22
-
23
- # XXX: int32 is size 4, bool is size 1. Why u no crash?
24
- def get_bool offset
25
- int = get_int32 offset
26
- return (int != 0)
27
- end
28
16
  end
29
17
  end
30
18
  end
@@ -1,36 +1,70 @@
1
1
  module GirFFI
2
2
  # The InOutPointer class handles conversion between ruby types and
3
3
  # pointers for arguments with direction :inout and :out.
4
+ #
5
+ # TODO: This has now become a more general extende pointer class and should be renamed.
4
6
  class InOutPointer < FFI::Pointer
5
7
  attr_reader :value_type
6
8
 
7
- def initialize value, type
8
- @ffi_type = TypeMap.type_specification_to_ffitype type
9
+ def initialize type, ptr = nil
9
10
  @value_type = type
10
11
 
11
- value = adjust_value_in value
12
-
13
- ptr = AllocationHelper.safe_malloc(FFI.type_size @ffi_type)
14
- ptr.send "put_#{@ffi_type}", 0, value
15
-
12
+ ptr ||= AllocationHelper.safe_malloc(value_type_size)
16
13
  super ptr
17
14
  end
18
15
 
19
16
  private :initialize
20
17
 
18
+ # TODO: Rename to get_value
21
19
  def to_value
22
- self.send "get_#{@ffi_type}", 0
20
+ case value_ffi_type
21
+ when Class
22
+ to_ptr
23
+ when Symbol
24
+ adjust_value_out self.send("get_#{value_ffi_type}", 0)
25
+ else
26
+ raise NotImplementedError
27
+ end
23
28
  end
24
29
 
25
- def self.for type
26
- if Array === type
27
- return self.new nil, *type
30
+ def set_value value
31
+ value = adjust_value_in value
32
+ case value_ffi_type
33
+ when Class
34
+ self.put_bytes 0, value.to_ptr.read_bytes(value_type_size), 0, value_type_size
35
+ when Symbol
36
+ self.send "put_#{value_ffi_type}", 0, value
37
+ else
38
+ raise NotImplementedError
28
39
  end
29
- self.new nil, type
40
+ end
41
+
42
+ def value_ffi_type
43
+ @value_ffi_type ||= case value_type
44
+ when :gboolean
45
+ :int
46
+ else
47
+ TypeMap.type_specification_to_ffitype value_type
48
+ end
49
+ end
50
+
51
+ def value_type_size
52
+ @value_type_size ||= case value_ffi_type
53
+ when Class
54
+ value_ffi_type.size
55
+ when Symbol
56
+ FFI.type_size value_ffi_type
57
+ else
58
+ raise NotImplementedError
59
+ end
60
+ end
61
+
62
+ def self.for type
63
+ self.new(type).tap {|ptr| ptr.set_value nil}
30
64
  end
31
65
 
32
66
  def self.from type, value
33
- self.new value, type
67
+ self.new(type).tap {|ptr| ptr.set_value value}
34
68
  end
35
69
 
36
70
  private
@@ -38,14 +72,23 @@ module GirFFI
38
72
  def adjust_value_in value
39
73
  case @value_type
40
74
  when :gboolean
41
- value
75
+ value ? 1 : 0
42
76
  else
43
77
  value || nil_value
44
78
  end
45
79
  end
46
80
 
81
+ def adjust_value_out value
82
+ case value_type
83
+ when :gboolean
84
+ value != 0
85
+ else
86
+ value
87
+ end
88
+ end
89
+
47
90
  def nil_value
48
- @ffi_type == :pointer ? nil : 0
91
+ value_ffi_type == :pointer ? nil : 0
49
92
  end
50
93
  end
51
94
  end
@@ -8,6 +8,8 @@ module GirFFI
8
8
  case type
9
9
  when :utf8, :filename
10
10
  from_utf8_array ary
11
+ when :gboolean
12
+ from_boolean_array ary
11
13
  when Symbol
12
14
  from_basic_type_array type, ary
13
15
  when Class
@@ -47,6 +49,10 @@ module GirFFI
47
49
  from_basic_type_array :pointer, ptr_ary
48
50
  end
49
51
 
52
+ def from_boolean_array ary
53
+ from_basic_type_array :int, ary.map {|val| val ? 1 : 0}
54
+ end
55
+
50
56
  def from_interface_pointer_array ary
51
57
  ptr_ary = ary.map {|ifc| ifc.to_ptr}
52
58
  ptr_ary << nil
@@ -65,6 +65,15 @@ module GirFFI
65
65
  end
66
66
  types.unshift(:pointer).push(:pointer)
67
67
  end
68
+
69
+ def return_ffi_type
70
+ result = super
71
+ if result == GLib::Boolean
72
+ :bool
73
+ else
74
+ result
75
+ end
76
+ end
68
77
  end
69
78
  end
70
79
  end
@@ -18,7 +18,7 @@ module GirFFI
18
18
  :array => :pointer,
19
19
  :utf8 => :pointer,
20
20
  :GType => gtype_type,
21
- :gboolean => :bool,
21
+ :gboolean => GLib::Boolean,
22
22
  :gunichar => :uint32,
23
23
  :gint8 => :int8,
24
24
  :guint8 => :uint8,
@@ -1,3 +1,3 @@
1
1
  module GirFFI
2
- VERSION = "0.6.5"
2
+ VERSION = "0.6.6"
3
3
  end
@@ -67,10 +67,15 @@ describe GLib::Array do
67
67
  assert_equal [1, 2, 3], arr.to_a
68
68
  end
69
69
 
70
- describe "::from" do
71
- it "creates a GArray from a Ruby array" do
70
+ describe ".from" do
71
+ it "creates a GArray from an array of :gint32" do
72
72
  arr = GLib::Array.from :gint32, [3, 2, 1]
73
- assert_equal [3, 2, 1], arr.to_a
73
+ arr.data.read_array_of_int32(3).must_equal [3, 2, 1]
74
+ end
75
+
76
+ it "creates a GArray from an array of :gboolean" do
77
+ arr = GLib::Array.from :gboolean, [true, false, true]
78
+ arr.data.read_array_of_int(3).must_equal [1, 0, 1]
74
79
  end
75
80
 
76
81
  it "return its argument if given a GArray" do
@@ -119,5 +124,27 @@ describe GLib::Array do
119
124
  arr.wont_be :==, other
120
125
  end
121
126
  end
122
- end
123
127
 
128
+ describe "#index" do
129
+ it "returns the proper element for an array of :gint32" do
130
+ arr = GLib::Array.from :gint32, [1, 2, 3]
131
+ arr.index(2).must_equal 3
132
+ end
133
+
134
+ it "returns the proper element for an array of :utf8" do
135
+ arr = GLib::Array.from :utf8, ["a", "b", "c"]
136
+ arr.index(1).must_equal "b"
137
+ end
138
+
139
+ it "returns the proper element for an array of :gboolean" do
140
+ arr = GLib::Array.from :gboolean, [true, false, true]
141
+ arr.index(1).must_equal false
142
+ end
143
+
144
+ it "returns the proper element for an array of struct" do
145
+ vals = [1, 2, 3].map {|i| GObject::EnumValue.new.tap {|ev| ev.value = i} }
146
+ arr = GLib::Array.from GObject::EnumValue, vals
147
+ arr.index(1).value.must_equal 2
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,27 @@
1
+ require 'gir_ffi_test_helper'
2
+
3
+ describe GLib::Boolean do
4
+ it "has the same native size as an int" do
5
+ FFI.type_size(GLib::Boolean).must_equal FFI.type_size :int
6
+ end
7
+
8
+ describe ".from_native" do
9
+ it "converts 0 to false" do
10
+ GLib::Boolean.from_native(0, "whatever").must_equal false
11
+ end
12
+
13
+ it "converts 1 to true" do
14
+ GLib::Boolean.from_native(1, "whatever").must_equal true
15
+ end
16
+ end
17
+
18
+ describe ".to_native" do
19
+ it "converts false to 0" do
20
+ GLib::Boolean.to_native(false, "whatever").must_equal 0
21
+ end
22
+
23
+ it "converts true to 1" do
24
+ GLib::Boolean.to_native(true, "whatever").must_equal 1
25
+ end
26
+ end
27
+ end
@@ -3,6 +3,15 @@ require 'gir_ffi_test_helper'
3
3
  require 'gir_ffi/in_out_pointer'
4
4
 
5
5
  describe GirFFI::InOutPointer do
6
+ describe ".new" do
7
+ it "wraps an existing pointer and a type" do
8
+ ptr = GirFFI::AllocationHelper.safe_malloc(FFI.type_size(:int32))
9
+ ptr.put_int32 0, 42
10
+ instance = GirFFI::InOutPointer.new :gint32, ptr
11
+ instance.to_value.must_equal 42
12
+ end
13
+ end
14
+
6
15
  describe "an instance created with .from" do
7
16
  before do
8
17
  @result = GirFFI::InOutPointer.from :gint32, 23
@@ -18,8 +27,14 @@ describe GirFFI::InOutPointer do
18
27
  end
19
28
 
20
29
  describe ".from" do
21
- it "handles :gboolean" do
22
- GirFFI::InOutPointer.from :gboolean, false
30
+ it "handles :gboolean false" do
31
+ ptr = GirFFI::InOutPointer.from :gboolean, false
32
+ ptr.read_int.must_equal 0
33
+ end
34
+
35
+ it "handles :gboolean true" do
36
+ ptr = GirFFI::InOutPointer.from :gboolean, true
37
+ ptr.read_int.must_equal(1)
23
38
  end
24
39
 
25
40
  it "handles :utf8 pointers" do
@@ -42,7 +57,7 @@ describe GirFFI::InOutPointer do
42
57
  end
43
58
  end
44
59
 
45
- describe "::for" do
60
+ describe ".for" do
46
61
  it "handles :gboolean" do
47
62
  GirFFI::InOutPointer.for :gboolean
48
63
  end
@@ -61,12 +76,12 @@ describe GirFFI::InOutPointer do
61
76
  describe "for :gboolean values" do
62
77
  it "works when the value is false" do
63
78
  ptr = GirFFI::InOutPointer.from :gboolean, false
64
- assert_equal false, ptr.to_value
79
+ ptr.to_value.must_equal false
65
80
  end
66
81
 
67
82
  it "works when the value is true" do
68
83
  ptr = GirFFI::InOutPointer.from :gboolean, true
69
- assert_equal true, ptr.to_value
84
+ ptr.to_value.must_equal true
70
85
  end
71
86
  end
72
87
 
@@ -77,5 +92,22 @@ describe GirFFI::InOutPointer do
77
92
  assert_equal "Some value", ptr.to_value.read_string
78
93
  end
79
94
  end
95
+
96
+ describe "for struct values" do
97
+ it "returns a pointer to the held value" do
98
+ val = GObject::EnumValue.new
99
+ val.value = 3
100
+ ptr = GirFFI::InOutPointer.from GObject::EnumValue, val
101
+ result = ptr.to_value
102
+ GObject::EnumValue.wrap(result).value.must_equal 3
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "#value_ffi_type" do
108
+ it "returns :int for the :gboolean value type" do
109
+ ptr = GirFFI::InOutPointer.from :gboolean, true
110
+ ptr.value_ffi_type.must_equal :int
111
+ end
80
112
  end
81
113
  end
@@ -2,6 +2,7 @@ require 'gir_ffi_test_helper'
2
2
 
3
3
  describe GirFFI::InfoExt::ISignalInfo do
4
4
  let(:klass) { Class.new do
5
+ include GirFFI::InfoExt::ICallableInfo
5
6
  include GirFFI::InfoExt::ISignalInfo
6
7
  end }
7
8
  let(:signal_info) { klass.new }
@@ -55,4 +56,15 @@ describe GirFFI::InfoExt::ISignalInfo do
55
56
  end
56
57
  end
57
58
  end
59
+
60
+ describe "#return_ffi_type" do
61
+ # FIXME: This is needed because callbacks are limited in the accepted
62
+ # types. This should be fixed in FFI.
63
+ it "returns :bool for the :gboolean type" do
64
+ stub(return_type_info = Object.new).to_ffitype { GLib::Boolean }
65
+ stub(signal_info).return_type { return_type_info }
66
+
67
+ signal_info.return_ffi_type.must_equal :bool
68
+ end
69
+ end
58
70
  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.6.5
4
+ version: 0.6.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-03 00:00:00.000000000 Z
12
+ date: 2013-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -170,6 +170,7 @@ files:
170
170
  - lib/gir_ffi/function_builder.rb
171
171
  - lib/gir_ffi-base/gir_ffi/library.rb
172
172
  - lib/gir_ffi-base/gobject/lib.rb
173
+ - lib/gir_ffi-base/glib/boolean.rb
173
174
  - lib/gir_ffi-base/glib/strv.rb
174
175
  - lib/ffi-gobject/ruby_style.rb
175
176
  - lib/ffi-gobject/ruby_closure.rb
@@ -266,6 +267,7 @@ files:
266
267
  - test/gir_ffi/info_ext/i_field_info_test.rb
267
268
  - test/gir_ffi/info_ext/i_function_info_test.rb
268
269
  - test/gir_ffi/interface_base_test.rb
270
+ - test/gir_ffi-base/glib/boolean_test.rb
269
271
  - test/gir_ffi-base/glib/strv_test.rb
270
272
  - test/ffi-gobject/object_class_test.rb
271
273
  - test/ffi-gobject/object_test.rb
@@ -358,6 +360,7 @@ test_files:
358
360
  - test/ffi-gobject_introspection/i_repository_test.rb
359
361
  - test/ffi-gobject_introspection/lib_test.rb
360
362
  - test/ffi-gobject_test.rb
363
+ - test/gir_ffi-base/glib/boolean_test.rb
361
364
  - test/gir_ffi-base/glib/strv_test.rb
362
365
  - test/gir_ffi/arg_helper_test.rb
363
366
  - test/gir_ffi/argument_builder_test.rb