gir_ffi 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +14 -0
  3. data/Gemfile +1 -1
  4. data/lib/ffi-gobject/ruby_closure.rb +1 -1
  5. data/lib/ffi-gobject/value.rb +0 -5
  6. data/lib/ffi-gobject.rb +2 -0
  7. data/lib/gir_ffi/allocation_helper.rb +6 -0
  8. data/lib/gir_ffi/boxed_base.rb +12 -6
  9. data/lib/gir_ffi/builders/c_to_ruby_convertor.rb +1 -1
  10. data/lib/gir_ffi/builders/callback_argument_builder.rb +5 -1
  11. data/lib/gir_ffi/builders/function_builder.rb +1 -1
  12. data/lib/gir_ffi/builders/initializer_return_value_builder.rb +3 -2
  13. data/lib/gir_ffi/builders/object_builder.rb +2 -1
  14. data/lib/gir_ffi/builders/struct_builder.rb +1 -1
  15. data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +1 -1
  16. data/lib/gir_ffi/builders/union_builder.rb +3 -2
  17. data/lib/gir_ffi/in_pointer.rb +13 -17
  18. data/lib/gir_ffi/object_base.rb +1 -1
  19. data/lib/gir_ffi/ownable.rb +16 -0
  20. data/lib/gir_ffi/struct.rb +9 -0
  21. data/lib/gir_ffi/struct_base.rb +3 -1
  22. data/lib/gir_ffi/struct_like_base.rb +15 -3
  23. data/lib/gir_ffi/union.rb +9 -0
  24. data/lib/gir_ffi/union_base.rb +2 -0
  25. data/lib/gir_ffi/version.rb +1 -1
  26. data/test/gir_ffi/boxed_base_test.rb +4 -4
  27. data/test/gir_ffi/builders/argument_builder_test.rb +1 -1
  28. data/test/gir_ffi/builders/function_builder_test.rb +27 -0
  29. data/test/gir_ffi/builders/initializer_builder_test.rb +2 -2
  30. data/test/gir_ffi/builders/return_value_builder_test.rb +1 -1
  31. data/test/gir_ffi/builders/union_builder_test.rb +2 -2
  32. data/test/gir_ffi/builders/vfunc_builder_test.rb +1 -1
  33. data/test/gir_ffi/class_base_test.rb +1 -1
  34. data/test/gir_ffi/in_out_pointer_test.rb +4 -4
  35. data/test/gir_ffi/in_pointer_test.rb +7 -7
  36. data/test/gir_ffi/sized_array_test.rb +3 -1
  37. data/test/gir_ffi/struct_base_test.rb +29 -3
  38. data/test/gir_ffi/union_base_test.rb +17 -3
  39. data/test/integration/generated_gimarshallingtests_test.rb +6 -9
  40. data/test/integration/generated_regress_test.rb +2 -1
  41. metadata +9 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 464fd086b86382dddea95e18946be4af246c36b4
4
- data.tar.gz: c9c13a75efe36d9a513c7ff8d9327b1aab20e8cb
3
+ metadata.gz: fa45cf6ed9c1af0159b7faeea5573b925d0fbff3
4
+ data.tar.gz: c016996c65de12f29c5133955b211d8ae0346f9d
5
5
  SHA512:
6
- metadata.gz: d3324bd949d9d9915d1656641d9ab19831aa884adfbd36df8690749450405f9b75721bac8104c8ec4c75baf2ceb079219338abd61b2c43bab5d731382190394f
7
- data.tar.gz: dffc23519a16b729b03372502594cb959733bd9c94305814829579cf99821e2d301173fd7cda51b82d0472136c33f78b0569f684f91701a20f34a37f7c85f298
6
+ metadata.gz: 21a3c042d42c4c441908818ba387905d8a397245adbdd112980d4fba07166954b997219327781b3ab461d3fb93c9abd47e9f3e5aee2b3264c23208bab3aec2b6
7
+ data.tar.gz: 412062c0492c572e3aa2d9fb2beda46665c43fdf5263c77b96afc2b9c6c66f4ecf6d7ac7bda7ae722ea93e929d04f995b69bb0521b10b34d239ceed2de89c4fd
data/Changelog.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.1 / 2016-03-28
4
+
5
+ * Restore JRuby compatibility.
6
+ - Introduce #owned to flag unions and structs for release at garbage collection time.
7
+ In JRuby's implementation, FFI::Pointer does not implement #autorelease=
8
+ and #autorelease?, so this different technique is used to free pointers
9
+ allocated by GLib. It is in fact doubtful that setting autorelease had any
10
+ actual effect even on CRuby.
11
+ - Immediately free string pointers whose ownership is transfered. Again, the
12
+ #autorelease technique doesn't work on JRuby.
13
+ - Fix handling of callee-allocated out parameters in vfuncs. The put_pointer
14
+ method was wrongly called, and JRuby is more picky about what types that
15
+ method expects, exposing the bug.
16
+
3
17
  ## 0.10.0 / 2016-03-23
4
18
 
5
19
  * Ensure ownership of created RubyClosure objects
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
4
4
  # The gem's dependencies are specified in gir_ffi.gemspec
5
5
  gemspec
6
6
 
7
- gem 'rubocop', '~> 0.37.0', type: :development
7
+ gem 'rubocop', '~> 0.38.0', type: :development
8
8
 
9
9
  if ENV['CI']
10
10
  if ENV['TRAVIS_RUBY_VERSION'] == '2.2'
@@ -11,7 +11,7 @@ module GObject
11
11
  # the object_id of the associated block.
12
12
  #
13
13
  # @api private
14
- class Struct < FFI::Struct
14
+ class Struct < GirFFI::Struct
15
15
  layout :parent, Closure::Struct, 0,
16
16
  :block_id, :int64
17
17
  end
@@ -207,10 +207,5 @@ module GObject
207
207
  METHOD_MAP[current_gtype] || METHOD_MAP[current_fundamental_type] ||
208
208
  raise("No method map entry for #{current_gtype_name}")
209
209
  end
210
-
211
- def make_finalizer
212
- gtype = self.class.gtype
213
- ObjectSpace.define_finalizer self, self.class.make_finalizer(@struct, gtype)
214
- end
215
210
  end
216
211
  end
data/lib/ffi-gobject.rb CHANGED
@@ -107,6 +107,8 @@ module GObject
107
107
 
108
108
  attach_function :g_param_spec_ref, [:pointer], :pointer
109
109
  attach_function :g_param_spec_sink, [:pointer], :pointer
110
+
111
+ attach_function :g_type_class_ref, [:size_t], :pointer
110
112
  end
111
113
 
112
114
  TYPE_ARRAY = Lib.g_array_get_type
@@ -21,5 +21,11 @@ module GirFFI
21
21
  type_size = FFI.type_size type
22
22
  safe_malloc(type_size)
23
23
  end
24
+
25
+ def self.free_after(ptr)
26
+ result = yield ptr
27
+ LibC.free ptr unless ptr.null?
28
+ result
29
+ end
24
30
  end
25
31
  end
@@ -8,15 +8,20 @@ module GirFFI
8
8
  store_pointer(self.class::Struct.new.to_ptr)
9
9
  end
10
10
 
11
- def self.make_finalizer(ptr, gtype)
11
+ def self.make_finalizer(struct, gtype)
12
12
  proc do
13
- if ptr.autorelease?
14
- ptr.autorelease = false
15
- GObject.boxed_free gtype, ptr
13
+ if struct.owned?
14
+ struct.owned = false
15
+ GObject.boxed_free gtype, struct.to_ptr
16
16
  end
17
17
  end
18
18
  end
19
19
 
20
+ # Wrap value and take ownership of it
21
+ def self.wrap_own(val)
22
+ wrap(val).tap { |it| it && it.struct.owned = true }
23
+ end
24
+
20
25
  # Create an unowned copy of the struct represented by val
21
26
  def self.copy_from(val)
22
27
  copy from(val)
@@ -24,7 +29,8 @@ module GirFFI
24
29
 
25
30
  # Wrap an owned copy of the struct represented by val
26
31
  def self.wrap_copy(val)
27
- copy(wrap(val)).tap { |it| it && it.to_ptr.autorelease = true }
32
+ # TODO: Is this needed? We may get away with just copying on transfer away from us.
33
+ copy(wrap(val)).tap { |it| it && it.struct.owned = true }
28
34
  end
29
35
 
30
36
  def self.copy(val)
@@ -42,7 +48,7 @@ module GirFFI
42
48
 
43
49
  def make_finalizer
44
50
  gtype = self.class.gtype
45
- ObjectSpace.define_finalizer self, self.class.make_finalizer(to_ptr, gtype)
51
+ ObjectSpace.define_finalizer self, self.class.make_finalizer(@struct, gtype)
46
52
  end
47
53
  end
48
54
  end
@@ -15,7 +15,7 @@ module GirFFI
15
15
  case @type_info.flattened_tag
16
16
  when :utf8, :filename
17
17
  if @ownership_transfer == :everything
18
- "#{@argument}.tap { |it| it.autorelease = true }.to_utf8"
18
+ "GirFFI::AllocationHelper.free_after #{@argument}, &:to_utf8"
19
19
  else
20
20
  "#{@argument}.to_utf8"
21
21
  end
@@ -90,7 +90,11 @@ module GirFFI
90
90
  end
91
91
 
92
92
  def pointer_value_convertor
93
- @pointer_value_convertor ||= PointerValueConvertor.new(type_spec)
93
+ @pointer_value_convertor ||= if allocated_by_us?
94
+ PointerValueConvertor.new(type_spec[1])
95
+ else
96
+ PointerValueConvertor.new(type_spec)
97
+ end
94
98
  end
95
99
 
96
100
  def pointer_to_value_conversion
@@ -28,7 +28,7 @@ module GirFFI
28
28
  end
29
29
 
30
30
  def function_call_arguments
31
- ca = argument_builder_collection.call_argument_names
31
+ ca = argument_builder_collection.call_argument_names.dup
32
32
  ca.unshift receiver_call_argument if @info.method?
33
33
  ca
34
34
  end
@@ -7,10 +7,11 @@ module GirFFI
7
7
  class InitializerReturnValueBuilder < BaseReturnValueBuilder
8
8
  def post_conversion
9
9
  result = []
10
+ result << "store_pointer(#{capture_variable_name})"
10
11
  if specialized_type_tag == :struct
11
- result << "#{capture_variable_name}.autorelease = true"
12
+ result << '@struct.owned = true'
12
13
  end
13
- result << "store_pointer(#{capture_variable_name})"
14
+ result
14
15
  end
15
16
  end
16
17
  end
@@ -3,6 +3,7 @@ require 'gir_ffi/builders/registered_type_builder'
3
3
  require 'gir_ffi/builders/with_layout'
4
4
  require 'gir_ffi/builders/property_builder'
5
5
  require 'gir_ffi/object_base'
6
+ require 'gir_ffi/struct'
6
7
 
7
8
  module GirFFI
8
9
  module Builders
@@ -74,7 +75,7 @@ module GirFFI
74
75
 
75
76
  # FIXME: Private method only used in subclass
76
77
  def layout_superclass
77
- FFI::Struct
78
+ GirFFI::Struct
78
79
  end
79
80
 
80
81
  def parent_info
@@ -10,7 +10,7 @@ module GirFFI
10
10
  include StructLike
11
11
 
12
12
  def layout_superclass
13
- FFI::Struct
13
+ GirFFI::Struct
14
14
  end
15
15
 
16
16
  def superclass
@@ -23,7 +23,7 @@ module GirFFI
23
23
  end
24
24
 
25
25
  def layout_superclass
26
- FFI::Struct
26
+ GirFFI::Struct
27
27
  end
28
28
  end
29
29
  end
@@ -2,16 +2,17 @@
2
2
  require 'gir_ffi/builders/registered_type_builder'
3
3
  require 'gir_ffi/builders/struct_like'
4
4
  require 'gir_ffi/union_base'
5
+ require 'gir_ffi/union'
5
6
 
6
7
  module GirFFI
7
8
  module Builders
8
9
  # Implements the creation of a class representing union type. The
9
- # class will have a nested FFI::Union class to represent its C union.
10
+ # class will have a nested GirFFI::Union class to represent its C union.
10
11
  class UnionBuilder < RegisteredTypeBuilder
11
12
  include StructLike
12
13
 
13
14
  def layout_superclass
14
- FFI::Union
15
+ GirFFI::Union
15
16
  end
16
17
 
17
18
  private
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  module GirFFI
3
- # The InPointer class handles conversion from ruby types to pointers for
3
+ # The InPointer module handles conversion from ruby types to pointers for
4
4
  # arguments with direction :in. This is used for arguments that are
5
5
  # arrays, strings, or interfaces.
6
- class InPointer < FFI::Pointer
6
+ module InPointer
7
7
  def self.from_array(type, ary)
8
8
  return unless ary
9
9
  case type
@@ -36,11 +36,11 @@ module GirFFI
36
36
  when :utf8, :filename
37
37
  from_utf8 val
38
38
  when :gint32, :guint32, :gint8, :GType
39
- new val
39
+ FFI::Pointer.new val
40
40
  when Class, :void
41
41
  val.to_ptr
42
42
  when Module
43
- new type[val]
43
+ FFI::Pointer.new type[val]
44
44
  else
45
45
  raise NotImplementedError, type
46
46
  end
@@ -77,12 +77,12 @@ module GirFFI
77
77
  type_size = FFI.type_size(ffi_type)
78
78
  length = ary.length
79
79
 
80
- ptr = AllocationHelper.safe_malloc type_size * (length + 1)
80
+ ptr = FFI::MemoryPointer.new type_size * (length + 1)
81
+ ptr.autorelease = false
81
82
  ary.each_with_index do |item, idx|
82
83
  type.copy_value_to_pointer item, ptr, idx * type_size
83
84
  end
84
- ptr.put_bytes length * type_size, "\0" * type_size, 0, type_size
85
- new ptr
85
+ ptr
86
86
  end
87
87
 
88
88
  def from_enum_array(type, ary)
@@ -93,24 +93,20 @@ module GirFFI
93
93
 
94
94
  def from_utf8(str)
95
95
  return unless str
96
- len = str.bytesize
97
- ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
98
- new ptr
96
+ ptr = FFI::MemoryPointer.from_string(str)
97
+ ptr.autorelease = false
98
+ ptr
99
99
  end
100
100
 
101
101
  private
102
102
 
103
103
  def from_basic_type_array(type, ary)
104
104
  ffi_type = TypeMap.type_specification_to_ffi_type type
105
- ary = ary.dup << null_value(ffi_type)
106
105
  type_size = FFI.type_size(ffi_type)
107
- block = AllocationHelper.safe_malloc type_size * ary.length
106
+ block = FFI::MemoryPointer.new type_size * (ary.length + 1)
107
+ block.autorelease = false
108
108
  block.send "put_array_of_#{ffi_type}", 0, ary
109
- new block
110
- end
111
-
112
- def null_value(ffi_type)
113
- ffi_type == :pointer ? nil : 0
109
+ block
114
110
  end
115
111
  end
116
112
  end
@@ -67,7 +67,7 @@ module GirFFI
67
67
  def self.object_class
68
68
  @object_class ||=
69
69
  begin
70
- ptr = GObject.type_class_ref(gtype).to_ptr
70
+ ptr = GObject::Lib.g_type_class_ref(gtype)
71
71
  gir_ffi_builder.object_class_struct.wrap ptr
72
72
  end
73
73
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GirFFI
4
+ # Module implementing the concept of ownership. Owned objects need to have
5
+ # their memory freed or ref count lowered when they're garbage collected.
6
+ # Note that this attribute is generally placed on the nested struct of an
7
+ # object, and the relevant action is performed when the object's finalizer is
8
+ # run.
9
+ module Ownable
10
+ attr_accessor :owned
11
+
12
+ def owned?
13
+ owned
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ require 'gir_ffi/ownable'
3
+
4
+ module GirFFI
5
+ # Struct that can be owned.
6
+ class Struct < FFI::Struct
7
+ include Ownable
8
+ end
9
+ end
@@ -9,11 +9,13 @@ module GirFFI
9
9
 
10
10
  def initialize
11
11
  @struct = self.class::Struct.new
12
+ @struct.owned = true
13
+ @struct.to_ptr.autorelease = false
12
14
  end
13
15
 
14
16
  # Wrap value and take ownership of it
15
17
  def self.wrap_own(val)
16
- wrap(val).tap { |it| it && it.to_ptr.autorelease = true }
18
+ own wrap(val)
17
19
  end
18
20
  end
19
21
  end
@@ -36,18 +36,30 @@ module GirFFI
36
36
 
37
37
  # Create an unowned copy of the struct represented by val
38
38
  def copy_from(val)
39
- copy(from(val)).tap { |it| it && it.to_ptr.autorelease = false }
39
+ disown copy from(val)
40
40
  end
41
41
 
42
42
  # Wrap an owned copy of the struct represented by val
43
43
  def wrap_copy(val)
44
- copy wrap(val)
44
+ own copy wrap(val)
45
+ end
46
+
47
+ def own(val)
48
+ val.struct.owned = true if val
49
+ val
50
+ end
51
+
52
+ def disown(val)
53
+ val.struct.owned = false if val
54
+ val
45
55
  end
46
56
 
47
57
  # Create a copy of the struct represented by val
48
58
  def copy(val)
49
59
  return unless val
50
- new.tap { |copy| copy_value_to_pointer(val, copy.to_ptr) }
60
+ new.tap do |copy|
61
+ copy_value_to_pointer(val, copy.to_ptr)
62
+ end
51
63
  end
52
64
  end
53
65
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ require 'gir_ffi/ownable'
3
+
4
+ module GirFFI
5
+ # Union that can be owned.
6
+ class Union < FFI::Union
7
+ include Ownable
8
+ end
9
+ end
@@ -9,6 +9,8 @@ module GirFFI
9
9
 
10
10
  def initialize
11
11
  @struct = self.class::Struct.new
12
+ @struct.owned = true
13
+ @struct.to_ptr.autorelease = false
12
14
  end
13
15
  end
14
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # Current GirFFI version
3
3
  module GirFFI
4
- VERSION = '0.10.0'.freeze
4
+ VERSION = '0.10.1'.freeze
5
5
  end
@@ -5,20 +5,20 @@ GirFFI.setup :GIMarshallingTests
5
5
 
6
6
  describe GirFFI::BoxedBase do
7
7
  describe 'wrap_copy' do
8
- it 'returns a wrapped copy with autorelease true' do
8
+ it 'returns a wrapped copy with owned true' do
9
9
  original = GIMarshallingTests::BoxedStruct.new
10
10
  copy = GIMarshallingTests::BoxedStruct.wrap_copy(original.to_ptr)
11
11
  copy.to_ptr.wont_equal original.to_ptr
12
- copy.to_ptr.must_be :autorelease?
12
+ copy.struct.must_be :owned?
13
13
  end
14
14
  end
15
15
 
16
16
  describe 'copy_from' do
17
- it 'returns a copy with autorelease false' do
17
+ it 'returns a copy with owned false' do
18
18
  original = GIMarshallingTests::BoxedStruct.new
19
19
  copy = GIMarshallingTests::BoxedStruct.copy_from(original)
20
20
  copy.to_ptr.wont_equal original.to_ptr
21
- copy.to_ptr.wont_be :autorelease?
21
+ copy.struct.wont_be :owned?
22
22
  end
23
23
  end
24
24
  end
@@ -354,7 +354,7 @@ describe GirFFI::Builders::ArgumentBuilder do
354
354
 
355
355
  it 'has the correct value for #post_conversion' do
356
356
  builder.post_conversion.must_equal [
357
- '_v2 = _v1.get_pointer(0).tap { |it| it.autorelease = true }.to_utf8'
357
+ '_v2 = GirFFI::AllocationHelper.free_after _v1.get_pointer(0), &:to_utf8'
358
358
  ]
359
359
  end
360
360
 
@@ -6,6 +6,16 @@ describe GirFFI::Builders::FunctionBuilder do
6
6
  let(:builder) { GirFFI::Builders::FunctionBuilder.new function_info }
7
7
  let(:code) { builder.method_definition }
8
8
 
9
+ describe 'generally' do
10
+ let(:function_info) { get_method_introspection_data 'GObject', 'Object', 'get_property' }
11
+
12
+ it 'returns the same result when called twice' do
13
+ original = builder.method_definition
14
+ copy = builder.method_definition
15
+ copy.must_equal original
16
+ end
17
+ end
18
+
9
19
  describe 'for Regress:test_array_fixed_out_objects' do
10
20
  let(:function_info) { get_introspection_data 'Regress', 'test_array_fixed_out_objects' }
11
21
  it 'builds a correct definition' do
@@ -448,6 +458,23 @@ describe GirFFI::Builders::FunctionBuilder do
448
458
  end
449
459
  end
450
460
 
461
+ describe 'string ownership transfer' do
462
+ describe 'for Regress.test_utf8_out' do
463
+ let(:function_info) { get_introspection_data 'Regress', 'test_utf8_out' }
464
+
465
+ it 'builds a correct definition' do
466
+ code.must_equal <<-CODE.reset_indentation
467
+ def self.test_utf8_out
468
+ _v1 = FFI::MemoryPointer.new :pointer
469
+ Regress::Lib.regress_test_utf8_out _v1
470
+ _v2 = GirFFI::AllocationHelper.free_after _v1.get_pointer(0), &:to_utf8
471
+ return _v2
472
+ end
473
+ CODE
474
+ end
475
+ end
476
+ end
477
+
451
478
  describe 'for functions with an allow-none ingoing parameter' do
452
479
  let(:function_info) { get_introspection_data 'Regress', 'test_utf8_null_in' }
453
480
  it 'builds correct definition with default parameter value' do
@@ -39,12 +39,12 @@ describe GirFFI::Builders::InitializerBuilder do
39
39
  get_method_introspection_data 'GIMarshallingTests', 'BoxedStruct', 'new'
40
40
  end
41
41
 
42
- it 'builds an initializer that sets autorelease to true' do
42
+ it 'builds an initializer that sets owned to true' do
43
43
  code.must_equal <<-CODE.reset_indentation
44
44
  def initialize
45
45
  _v1 = GIMarshallingTests::Lib.gi_marshalling_tests_boxed_struct_new
46
- _v1.autorelease = true
47
46
  store_pointer(_v1)
47
+ @struct.owned = true
48
48
  end
49
49
  CODE
50
50
  end
@@ -347,7 +347,7 @@ describe GirFFI::Builders::ReturnValueBuilder do
347
347
  it 'autoreleases and converts the result in #post_conversion' do
348
348
  builder.capture_variable_name.must_equal '_v1'
349
349
  builder.post_conversion.
350
- must_equal ['_v2 = _v1.tap { |it| it.autorelease = true }.to_utf8']
350
+ must_equal ['_v2 = GirFFI::AllocationHelper.free_after _v1, &:to_utf8']
351
351
  end
352
352
 
353
353
  it 'returns the converted result' do
@@ -23,8 +23,8 @@ describe GirFFI::Builders::UnionBuilder do
23
23
  end
24
24
 
25
25
  describe '#layout_superclass' do
26
- it 'returns FFI::Union' do
27
- builder.layout_superclass.must_equal FFI::Union
26
+ it 'returns GirFFI::Union' do
27
+ builder.layout_superclass.must_equal GirFFI::Union
28
28
  end
29
29
  end
30
30
  end
@@ -101,7 +101,7 @@ describe GirFFI::Builders::VFuncBuilder do
101
101
  _v2 = arg
102
102
  _v3 = GirFFI::AllocationHelper.allocate(:int8).tap { |ptr| out.put_pointer 0, ptr }
103
103
  _v4 = _proc.call(_v1, _v2)
104
- _v3.put_pointer 0, _v4
104
+ _v3.put_int8 0, _v4
105
105
  end
106
106
  CODE
107
107
 
@@ -5,7 +5,7 @@ describe GirFFI::ClassBase do
5
5
  describe 'a simple descendant' do
6
6
  let(:klass) do
7
7
  Class.new(GirFFI::ClassBase) do
8
- self::Struct = Class.new(FFI::Struct) do
8
+ self::Struct = Class.new(GirFFI::Struct) do
9
9
  layout :foo, :int32
10
10
  end
11
11
  end
@@ -14,20 +14,20 @@ describe GirFFI::InOutPointer do
14
14
  describe '#to_value' do
15
15
  it 'returns the held value' do
16
16
  ptr = GirFFI::InOutPointer.allocate_new :gint32
17
- ptr.write_int32 123
17
+ ptr.put_int32 0, 123
18
18
  assert_equal 123, ptr.to_value
19
19
  end
20
20
 
21
21
  describe 'for :gboolean values' do
22
22
  it 'works when the value is false' do
23
23
  ptr = GirFFI::InOutPointer.allocate_new :gboolean
24
- ptr.write_int 0
24
+ ptr.put_int 0, 0
25
25
  ptr.to_value.must_equal false
26
26
  end
27
27
 
28
28
  it 'works when the value is true' do
29
29
  ptr = GirFFI::InOutPointer.allocate_new :gboolean
30
- ptr.write_int 1
30
+ ptr.put_int 0, 1
31
31
  ptr.to_value.must_equal true
32
32
  end
33
33
  end
@@ -36,7 +36,7 @@ describe GirFFI::InOutPointer do
36
36
  it 'returns a pointer to the held string value' do
37
37
  str_ptr = GirFFI::InPointer.from_utf8 'Some value'
38
38
  ptr = GirFFI::InOutPointer.allocate_new :utf8
39
- ptr.write_pointer str_ptr
39
+ ptr.put_pointer 0, str_ptr
40
40
  assert_equal 'Some value', ptr.to_value.read_string
41
41
  end
42
42
  end
@@ -25,7 +25,7 @@ describe GirFFI::InPointer do
25
25
 
26
26
  it 'handles struct types' do
27
27
  e = Class.new(GirFFI::StructBase) do
28
- self::Struct = Class.new(FFI::Struct) do
28
+ self::Struct = Class.new(GirFFI::Struct) do
29
29
  layout :foo, :int32, :bar, :int32
30
30
  end
31
31
  end
@@ -65,8 +65,8 @@ describe GirFFI::InPointer do
65
65
  assert_equal 13, @result.get_int(4)
66
66
  end
67
67
 
68
- it 'is an instance of GirFFI::InPointer' do
69
- assert_instance_of GirFFI::InPointer, @result
68
+ it 'is an instance of FFI::MemoryPointer' do
69
+ @result.must_be_instance_of FFI::MemoryPointer
70
70
  end
71
71
 
72
72
  it 'is zero-terminated' do
@@ -105,8 +105,8 @@ describe GirFFI::InPointer do
105
105
  assert_equal 'foo', @result.read_string
106
106
  end
107
107
 
108
- it 'is an instance of GirFFI::InPointer' do
109
- assert_instance_of GirFFI::InPointer, @result
108
+ it 'is an instance of FFI::MemoryPointer' do
109
+ @result.must_be_instance_of FFI::MemoryPointer
110
110
  end
111
111
  end
112
112
 
@@ -119,8 +119,8 @@ describe GirFFI::InPointer do
119
119
  assert_equal 12_345, @result.address
120
120
  end
121
121
 
122
- it 'is an instance of GirFFI::InPointer' do
123
- assert_instance_of GirFFI::InPointer, @result
122
+ it 'is an instance of FFI::Pointer' do
123
+ @result.must_be_instance_of FFI::Pointer
124
124
  end
125
125
  end
126
126
 
@@ -93,6 +93,8 @@ describe GirFFI::SizedArray do
93
93
  it 'creates unowned copies of struct pointer elements' do
94
94
  struct = GIMarshallingTests::BoxedStruct.new
95
95
  struct.long_ = 2342
96
+ struct.struct.must_be :owned?
97
+
96
98
  arr = GirFFI::SizedArray.copy_from([:pointer, GIMarshallingTests::BoxedStruct],
97
99
  1,
98
100
  [struct])
@@ -102,7 +104,7 @@ describe GirFFI::SizedArray do
102
104
  struct_copy = arr.first
103
105
  struct_copy.long_.must_equal struct.long_
104
106
  struct_copy.to_ptr.wont_equal struct.to_ptr
105
- struct_copy.to_ptr.wont_be :autorelease?
107
+ struct_copy.struct.wont_be :owned?
106
108
  end
107
109
 
108
110
  it 'increases the ref count of object pointer elements' do
@@ -4,21 +4,47 @@ require 'gir_ffi_test_helper'
4
4
  GirFFI.setup :GIMarshallingTests
5
5
 
6
6
  describe GirFFI::StructBase do
7
+ describe 'new' do
8
+ it 'creates an instance with an owned struct' do
9
+ instance = GIMarshallingTests::SimpleStruct.new
10
+ instance.struct.must_be :owned?
11
+ end
12
+
13
+ it 'ensures the wrapped pointer is not autoreleased' do
14
+ instance = GIMarshallingTests::SimpleStruct.new
15
+ instance.to_ptr.wont_be :autorelease?
16
+ end
17
+ end
18
+
7
19
  describe 'wrap_copy' do
8
- it 'returns a wrapped copy with autorelease true' do
20
+ it 'returns a wrapped owned copy' do
9
21
  original = GIMarshallingTests::SimpleStruct.new
10
22
  copy = GIMarshallingTests::SimpleStruct.wrap_copy(original.to_ptr)
11
23
  copy.to_ptr.wont_equal original.to_ptr
12
- copy.to_ptr.must_be :autorelease?
24
+ copy.to_ptr.wont_be :autorelease?
25
+ copy.struct.must_be :owned?
13
26
  end
14
27
  end
15
28
 
16
29
  describe 'copy_from' do
17
- it 'returns a copy with autorelease false' do
30
+ it 'returns an unowned copy' do
18
31
  original = GIMarshallingTests::SimpleStruct.new
19
32
  copy = GIMarshallingTests::SimpleStruct.copy_from(original)
20
33
  copy.to_ptr.wont_equal original.to_ptr
21
34
  copy.to_ptr.wont_be :autorelease?
35
+ copy.struct.wont_be :owned?
36
+ end
37
+ end
38
+
39
+ describe 'wrap_own' do
40
+ it 'wraps and owns the supplied value' do
41
+ original = GIMarshallingTests::SimpleStruct.new
42
+ original.struct.owned = false
43
+
44
+ copy = GIMarshallingTests::SimpleStruct.wrap_own(original.to_ptr)
45
+ copy.to_ptr.must_equal original.to_ptr
46
+ copy.to_ptr.wont_be :autorelease?
47
+ copy.struct.must_be :owned?
22
48
  end
23
49
  end
24
50
  end
@@ -4,21 +4,35 @@ require 'gir_ffi_test_helper'
4
4
  GirFFI.setup :GIMarshallingTests
5
5
 
6
6
  describe GirFFI::UnionBase do
7
+ describe 'new' do
8
+ it 'creates an instance with an owned struct' do
9
+ instance = GIMarshallingTests::Union.new
10
+ instance.struct.must_be :owned?
11
+ end
12
+
13
+ it 'ensures the wrapped pointer is not autoreleased' do
14
+ instance = GIMarshallingTests::Union.new
15
+ instance.to_ptr.wont_be :autorelease?
16
+ end
17
+ end
18
+
7
19
  describe 'wrap_copy' do
8
- it 'returns a wrapped copy with autorelease true' do
20
+ it 'returns a wrapped owned copy' do
9
21
  original = GIMarshallingTests::Union.new
10
22
  copy = GIMarshallingTests::Union.wrap_copy(original.to_ptr)
11
23
  copy.to_ptr.wont_equal original.to_ptr
12
- copy.to_ptr.must_be :autorelease?
24
+ copy.to_ptr.wont_be :autorelease?
25
+ copy.struct.must_be :owned?
13
26
  end
14
27
  end
15
28
 
16
29
  describe 'copy_from' do
17
- it 'returns a copy with autorelease false' do
30
+ it 'returns an unowned copy' do
18
31
  original = GIMarshallingTests::Union.new
19
32
  copy = GIMarshallingTests::Union.copy_from(original)
20
33
  copy.to_ptr.wont_equal original.to_ptr
21
34
  copy.to_ptr.wont_be :autorelease?
35
+ copy.struct.wont_be :owned?
22
36
  end
23
37
  end
24
38
  end
@@ -45,7 +45,7 @@ describe GIMarshallingTests do
45
45
  it 'creates an instance using #new' do
46
46
  bx = GIMarshallingTests::BoxedStruct.new
47
47
  assert_instance_of GIMarshallingTests::BoxedStruct, bx
48
- bx.to_ptr.must_be :autorelease?
48
+ bx.struct.must_be :owned?
49
49
  end
50
50
 
51
51
  it 'has a working method #inv' do
@@ -57,27 +57,24 @@ describe GIMarshallingTests do
57
57
  it 'has a working function #inout' do
58
58
  bx = GIMarshallingTests::BoxedStruct.new
59
59
  bx.long_ = 42
60
- bx.to_ptr.must_be :autorelease?
61
-
62
- # FIXME: Temporary check method
63
- bx.to_ptr.autorelease = true
60
+ bx.struct.must_be :owned?
64
61
 
65
62
  res = GIMarshallingTests::BoxedStruct.inout bx
66
- bx.to_ptr.must_be :autorelease?
67
- res.to_ptr.must_be :autorelease?
63
+ bx.struct.must_be :owned?
64
+ res.struct.must_be :owned?
68
65
 
69
66
  assert_equal 0, res.long_
70
67
  end
71
68
 
72
69
  it 'has a working function #out' do
73
70
  res = GIMarshallingTests::BoxedStruct.out
74
- res.to_ptr.must_be :autorelease?
71
+ res.struct.must_be :owned?
75
72
  assert_equal 42, res.long_
76
73
  end
77
74
 
78
75
  it 'has a working function #returnv' do
79
76
  res = GIMarshallingTests::BoxedStruct.returnv
80
- res.to_ptr.must_be :autorelease?
77
+ res.struct.must_be :owned?
81
78
  assert_equal 42, res.long_
82
79
  res.g_strv.must_be :==, %w(0 1 2)
83
80
  end
@@ -2564,7 +2564,7 @@ describe Regress do
2564
2564
 
2565
2565
  it 'has a writable field data1' do
2566
2566
  instance.data1.must_be :null?
2567
- instance.data1 = GirFFI::AllocationHelper.allocate(:int32).tap { |it| it.write_int(42) }
2567
+ instance.data1 = GirFFI::AllocationHelper.allocate(:int32).tap { |it| it.put_int(0, 42) }
2568
2568
  instance.data1.read_int.must_equal 42
2569
2569
  end
2570
2570
 
@@ -2744,6 +2744,7 @@ describe Regress do
2744
2744
  end
2745
2745
 
2746
2746
  it 'has a working function #annotation_return_filename' do
2747
+ skip 'This function is wrongly annotated as transfer-ownership: full'
2747
2748
  Regress.annotation_return_filename.must_equal 'a utf-8 filename'
2748
2749
  end
2749
2750
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gir_ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matijs van Zuijlen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-23 00:00:00.000000000 Z
11
+ date: 2016-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '10.1'
103
+ version: '11.1'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '10.1'
110
+ version: '11.1'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: aruba
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.12.0
117
+ version: 0.14.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.12.0
124
+ version: 0.14.1
125
125
  description: |2
126
126
  GirFFI creates bindings for GObject-based libraries at runtime based on introspection
127
127
  data provided by the GObject Introspection Repository (GIR) system. Bindings are created
@@ -293,6 +293,7 @@ files:
293
293
  - lib/gir_ffi/module_base.rb
294
294
  - lib/gir_ffi/object_base.rb
295
295
  - lib/gir_ffi/object_store.rb
296
+ - lib/gir_ffi/ownable.rb
296
297
  - lib/gir_ffi/property_not_found_error.rb
297
298
  - lib/gir_ffi/receiver_argument_info.rb
298
299
  - lib/gir_ffi/receiver_type_info.rb
@@ -300,6 +301,7 @@ files:
300
301
  - lib/gir_ffi/return_value_info.rb
301
302
  - lib/gir_ffi/signal_not_found_error.rb
302
303
  - lib/gir_ffi/sized_array.rb
304
+ - lib/gir_ffi/struct.rb
303
305
  - lib/gir_ffi/struct_base.rb
304
306
  - lib/gir_ffi/struct_like_base.rb
305
307
  - lib/gir_ffi/type_base.rb
@@ -307,6 +309,7 @@ files:
307
309
  - lib/gir_ffi/unintrospectable_boxed_info.rb
308
310
  - lib/gir_ffi/unintrospectable_signal_info.rb
309
311
  - lib/gir_ffi/unintrospectable_type_info.rb
312
+ - lib/gir_ffi/union.rb
310
313
  - lib/gir_ffi/union_base.rb
311
314
  - lib/gir_ffi/user_defined_property_info.rb
312
315
  - lib/gir_ffi/user_defined_type_info.rb