gir_ffi 0.9.5 → 0.10.0.pre1

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +9 -0
  3. data/lib/ffi-glib/byte_array.rb +1 -1
  4. data/lib/ffi-glib/bytes.rb +4 -4
  5. data/lib/ffi-glib/container_class_methods.rb +2 -0
  6. data/lib/ffi-glib/iconv.rb +2 -2
  7. data/lib/ffi-glib/variant.rb +10 -2
  8. data/lib/ffi-gobject.rb +6 -14
  9. data/lib/ffi-gobject/object.rb +7 -0
  10. data/lib/ffi-gobject/object_class.rb +1 -1
  11. data/lib/ffi-gobject/param_spec.rb +12 -0
  12. data/lib/ffi-gobject/value.rb +20 -11
  13. data/lib/gir_ffi-base/gobject.rb +35 -3
  14. data/lib/gir_ffi-base/gobject/lib.rb +2 -0
  15. data/lib/gir_ffi/allocation_helper.rb +11 -0
  16. data/lib/gir_ffi/arg_helper.rb +4 -0
  17. data/lib/gir_ffi/boxed_base.rb +28 -32
  18. data/lib/gir_ffi/builders/argument_builder.rb +31 -6
  19. data/lib/gir_ffi/builders/c_to_ruby_convertor.rb +36 -7
  20. data/lib/gir_ffi/builders/callback_argument_builder.rb +24 -10
  21. data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +1 -1
  22. data/lib/gir_ffi/builders/field_builder.rb +28 -10
  23. data/lib/gir_ffi/builders/full_c_to_ruby_convertor.rb +2 -3
  24. data/lib/gir_ffi/builders/initializer_return_value_builder.rb +5 -1
  25. data/lib/gir_ffi/builders/null_argument_builder.rb +0 -12
  26. data/lib/gir_ffi/builders/pointer_value_convertor.rb +38 -0
  27. data/lib/gir_ffi/builders/return_value_builder.rb +12 -10
  28. data/lib/gir_ffi/builders/ruby_to_c_convertor.rb +21 -2
  29. data/lib/gir_ffi/builders/struct_builder.rb +9 -2
  30. data/lib/gir_ffi/builders/{boxed_builder.rb → struct_like.rb} +2 -5
  31. data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +5 -2
  32. data/lib/gir_ffi/builders/union_builder.rb +5 -2
  33. data/lib/gir_ffi/enum_base.rb +4 -0
  34. data/lib/gir_ffi/error_argument_info.rb +0 -16
  35. data/lib/gir_ffi/ffi_ext/pointer.rb +11 -5
  36. data/lib/gir_ffi/flags_base.rb +4 -0
  37. data/lib/gir_ffi/in_out_pointer.rb +5 -30
  38. data/lib/gir_ffi/in_pointer.rb +5 -4
  39. data/lib/gir_ffi/info_ext/i_type_info.rb +3 -5
  40. data/lib/gir_ffi/object_base.rb +4 -0
  41. data/lib/gir_ffi/sized_array.rb +20 -0
  42. data/lib/gir_ffi/struct_base.rb +13 -2
  43. data/lib/gir_ffi/struct_like_base.rb +53 -0
  44. data/lib/gir_ffi/union_base.rb +7 -1
  45. data/lib/gir_ffi/version.rb +1 -1
  46. data/test/ffi-glib/destroy_notify_test.rb +4 -1
  47. data/test/ffi-gobject/param_spec_test.rb +18 -0
  48. data/test/gir_ffi/arg_helper_test.rb +17 -0
  49. data/test/gir_ffi/boxed_base_test.rb +24 -0
  50. data/test/gir_ffi/builders/argument_builder_test.rb +156 -63
  51. data/test/gir_ffi/builders/callback_argument_builder_test.rb +10 -10
  52. data/test/gir_ffi/builders/callback_builder_test.rb +31 -8
  53. data/test/gir_ffi/builders/field_builder_test.rb +32 -30
  54. data/test/gir_ffi/builders/function_builder_test.rb +251 -45
  55. data/test/gir_ffi/builders/initializer_builder_test.rb +17 -1
  56. data/test/gir_ffi/builders/return_value_builder_test.rb +115 -68
  57. data/test/gir_ffi/builders/struct_builder_test.rb +6 -0
  58. data/test/gir_ffi/builders/unintrospectable_builder_test.rb +4 -1
  59. data/test/gir_ffi/builders/vfunc_builder_test.rb +10 -10
  60. data/test/gir_ffi/in_out_pointer_test.rb +12 -81
  61. data/test/gir_ffi/in_pointer_test.rb +0 -17
  62. data/test/gir_ffi/info_ext/i_type_info_test.rb +0 -10
  63. data/test/gir_ffi/sized_array_test.rb +62 -0
  64. data/test/gir_ffi/struct_base_test.rb +24 -0
  65. data/test/gir_ffi/union_base_test.rb +24 -0
  66. data/test/gir_ffi/version_test.rb +1 -1
  67. data/test/integration/generated_gimarshallingtests_test.rb +32 -12
  68. data/test/integration/generated_regress_test.rb +9 -12
  69. metadata +12 -8
  70. data/lib/ffi-gobject/base.rb +0 -27
  71. data/lib/gir_ffi/user_data_argument_info.rb +0 -24
  72. data/lib/gir_ffi/user_data_type_info.rb +0 -22
@@ -1,15 +1,12 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/builders/registered_type_builder'
3
2
  require 'gir_ffi/builders/with_layout'
4
3
 
5
4
  module GirFFI
6
5
  module Builders
7
- # Implements the creation of a class representing boxed types.
8
- class BoxedBuilder < RegisteredTypeBuilder
6
+ # Implements base methods used by struct and union builders
7
+ module StructLike
9
8
  include WithLayout
10
9
 
11
- private
12
-
13
10
  def setup_class
14
11
  setup_layout
15
12
  setup_constants
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/builders/boxed_builder'
2
+ require 'gir_ffi/builders/registered_type_builder'
3
+ require 'gir_ffi/builders/struct_like'
3
4
 
4
5
  module GirFFI
5
6
  module Builders
6
7
  # Implements the creation of a class representing a boxed type for
7
8
  # which no data is found in the GIR.
8
- class UnintrospectableBoxedBuilder < BoxedBuilder
9
+ class UnintrospectableBoxedBuilder < RegisteredTypeBuilder
10
+ include StructLike
11
+
9
12
  def klass
10
13
  @klass ||= TypeBuilder::CACHE[target_gtype] ||= Class.new(superclass)
11
14
  end
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/builders/boxed_builder'
2
+ require 'gir_ffi/builders/registered_type_builder'
3
+ require 'gir_ffi/builders/struct_like'
3
4
  require 'gir_ffi/union_base'
4
5
 
5
6
  module GirFFI
6
7
  module Builders
7
8
  # Implements the creation of a class representing union type. The
8
9
  # class will have a nested FFI::Union class to represent its C union.
9
- class UnionBuilder < BoxedBuilder
10
+ class UnionBuilder < RegisteredTypeBuilder
11
+ include StructLike
12
+
10
13
  def layout_superclass
11
14
  FFI::Union
12
15
  end
@@ -31,6 +31,10 @@ module GirFFI
31
31
  self[arg]
32
32
  end
33
33
 
34
+ def size
35
+ native_type.size
36
+ end
37
+
34
38
  def copy_value_to_pointer(value, pointer)
35
39
  pointer.put_int32 0, to_native(value, nil)
36
40
  end
@@ -4,10 +4,6 @@ require 'gir_ffi/error_type_info'
4
4
  module GirFFI
5
5
  # Represents an error argument with the same interface as IArgumentInfo
6
6
  class ErrorArgumentInfo
7
- def skip?
8
- false
9
- end
10
-
11
7
  def direction
12
8
  :error
13
9
  end
@@ -19,17 +15,5 @@ module GirFFI
19
15
  def name
20
16
  '_error'
21
17
  end
22
-
23
- def closure
24
- -1
25
- end
26
-
27
- def destroy
28
- -1
29
- end
30
-
31
- def caller_allocates?
32
- true
33
- end
34
18
  end
35
19
  end
@@ -7,10 +7,6 @@ module GirFFI
7
7
  self
8
8
  end
9
9
 
10
- def to_value
11
- self
12
- end
13
-
14
10
  def zero?
15
11
  null?
16
12
  end
@@ -29,5 +25,15 @@ module GirFFI
29
25
  end
30
26
  end
31
27
 
32
- # TODO: Move use to InPointer and InOutPointer?
33
28
  FFI::Pointer.send :include, GirFFI::FFIExt::Pointer
29
+
30
+ FFI::Pointer.class_eval do
31
+ case FFI.type_size(:size_t)
32
+ when 4
33
+ alias_method :get_size_t, :get_uint32
34
+ when 8
35
+ alias_method :get_size_t, :get_uint64
36
+ end
37
+
38
+ alias_method :get_gtype, :get_size_t
39
+ end
@@ -35,6 +35,10 @@ module GirFFI
35
35
  self[arg]
36
36
  end
37
37
 
38
+ def size
39
+ native_type.size
40
+ end
41
+
38
42
  def copy_value_to_pointer(value, pointer)
39
43
  pointer.put_int32 0, to_native(value, nil)
40
44
  end
@@ -3,18 +3,14 @@ module GirFFI
3
3
  # The InOutPointer class handles conversion between ruby types and
4
4
  # pointers for arguments with direction :inout and :out.
5
5
  #
6
- # TODO: This has now become a more general extended pointer class and should be renamed.
7
6
  class InOutPointer < FFI::Pointer
8
7
  attr_reader :value_type
9
8
 
10
- def initialize(type, ptr = nil)
9
+ def initialize(type, ptr)
11
10
  @value_type = type
12
-
13
- ptr ||= AllocationHelper.safe_malloc(value_type_size)
14
11
  super ptr
15
12
  end
16
13
 
17
- # TODO: Create type classes that extract values from pointers.
18
14
  def to_value
19
15
  case value_ffi_type
20
16
  when Module
@@ -41,27 +37,10 @@ module GirFFI
41
37
  end
42
38
  end
43
39
 
44
- def set_value(value)
45
- case value_ffi_type
46
- when Module
47
- value_ffi_type.copy_value_to_pointer(value, self)
48
- when Symbol
49
- send "put_#{value_ffi_type}", 0, value
50
- else
51
- raise NotImplementedError, value_ffi_type
52
- end
53
- end
54
-
55
- def clear
56
- put_bytes 0, "\x00" * value_type_size, 0, value_type_size
57
- end
58
-
59
- def self.for(type)
60
- new(type).tap(&:clear)
61
- end
62
-
63
- def self.from(type, value)
64
- new(type).tap { |ptr| ptr.set_value value }
40
+ def self.allocate_new(type)
41
+ ffi_type = TypeMap.type_specification_to_ffi_type type
42
+ ptr = AllocationHelper.allocate(ffi_type)
43
+ new type, ptr
65
44
  end
66
45
 
67
46
  private
@@ -69,9 +48,5 @@ module GirFFI
69
48
  def value_ffi_type
70
49
  @value_ffi_type ||= TypeMap.type_specification_to_ffi_type value_type
71
50
  end
72
-
73
- def value_type_size
74
- @value_type_size ||= FFI.type_size value_ffi_type
75
- end
76
51
  end
77
52
  end
@@ -47,10 +47,6 @@ module GirFFI
47
47
  end
48
48
 
49
49
  class << self
50
- def from_closure_data(obj)
51
- ArgHelper::OBJECT_STORE.store(obj)
52
- end
53
-
54
50
  private
55
51
 
56
52
  def from_utf8_array(ary)
@@ -93,12 +89,17 @@ module GirFFI
93
89
  from_basic_type_array :int32, ary.map { |sym| type.to_native sym, nil }
94
90
  end
95
91
 
92
+ public
93
+
96
94
  def from_utf8(str)
95
+ return unless str
97
96
  len = str.bytesize
98
97
  ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
99
98
  new ptr
100
99
  end
101
100
 
101
+ private
102
+
102
103
  def from_basic_type_array(type, ary)
103
104
  ffi_type = TypeMap.type_specification_to_ffi_type type
104
105
  ary = ary.dup << null_value(ffi_type)
@@ -81,8 +81,8 @@ module GirFFI
81
81
  gslist: 'GLib::SList',
82
82
  ptr_array: 'GLib::PtrArray',
83
83
  strv: 'GLib::Strv',
84
- utf8: 'GirFFI::InPointer',
85
- void: 'GirFFI::InPointer',
84
+ utf8: 'GirFFI::InPointer', # TODO: Create a string-like class
85
+ void: 'GirFFI::InPointer', # TODO: Create a void-pointer class
86
86
  zero_terminated: 'GirFFI::ZeroTerminated'
87
87
  }.freeze
88
88
 
@@ -130,7 +130,7 @@ module GirFFI
130
130
 
131
131
  TAGS_NEEDING_RUBY_TO_C_CONVERSION = [
132
132
  :array, :c, :callback, :error, :ghash, :glist, :gslist, :object,
133
- :ptr_array, :struct, :strv, :utf8, :void, :zero_terminated
133
+ :ptr_array, :struct, :strv, :utf8, :zero_terminated
134
134
  ].freeze
135
135
 
136
136
  TAGS_NEEDING_C_TO_RUBY_CONVERSION = [
@@ -175,8 +175,6 @@ module GirFFI
175
175
 
176
176
  def extra_conversion_arguments
177
177
  case flattened_tag
178
- when :utf8, :void
179
- [flattened_tag]
180
178
  when :c
181
179
  [element_type, array_fixed_size]
182
180
  when :array, :ghash, :glist, :gslist, :ptr_array, :zero_terminated
@@ -36,6 +36,10 @@ module GirFFI
36
36
  ptr.to_object
37
37
  end
38
38
 
39
+ def self.copy_from(val)
40
+ val.ref if val
41
+ end
42
+
39
43
  #
40
44
  # Find property info for the named property.
41
45
  #
@@ -71,6 +71,26 @@ module GirFFI
71
71
  end
72
72
  end
73
73
 
74
+ def copy_from(element_type, size, item)
75
+ return unless item
76
+
77
+ enumerable = case item
78
+ when FFI::Pointer
79
+ wrap(element_type, size, item).to_a
80
+ when self
81
+ item.to_a
82
+ else
83
+ item
84
+ end
85
+ case element_type
86
+ when Array
87
+ _main_type, sub_type = *element_type
88
+ enumerable = enumerable.map { |it| sub_type.copy_from it }
89
+ end
90
+
91
+ from_enumerable element_type, size, enumerable
92
+ end
93
+
74
94
  private
75
95
 
76
96
  def from_sized_array(size, sized_array)
@@ -1,8 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/boxed_base'
2
+ require 'gir_ffi/struct_like_base'
3
3
 
4
4
  module GirFFI
5
5
  # Base class for generated classes representing GLib structs.
6
- class StructBase < BoxedBase
6
+ class StructBase < ClassBase
7
+ extend FFI::DataConverter
8
+ extend GirFFI::StructLikeBase
9
+
10
+ def initialize
11
+ @struct = self.class::Struct.new
12
+ end
13
+
14
+ # Wrap value and take ownership of it
15
+ def self.wrap_own(val)
16
+ wrap(val).tap { |it| it && it.to_ptr.autorelease = true }
17
+ end
7
18
  end
8
19
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ module GirFFI
3
+ # Base module providing class methods for generated classes representing GLib
4
+ # structs, unions and boxed types.
5
+ module StructLikeBase
6
+ def native_type
7
+ FFI::Type::Struct.new(self::Struct)
8
+ end
9
+
10
+ def to_ffi_type
11
+ self
12
+ end
13
+
14
+ # NOTE: Needed for JRuby's FFI
15
+ def to_native(value, _context)
16
+ value.struct
17
+ end
18
+
19
+ def get_value_from_pointer(pointer, offset)
20
+ pointer + offset
21
+ end
22
+
23
+ def size
24
+ self::Struct.size
25
+ end
26
+
27
+ def copy_value_to_pointer(value, pointer, offset = 0)
28
+ size = self::Struct.size
29
+ bytes = if value
30
+ value.to_ptr.read_bytes(size)
31
+ else
32
+ "\x00" * size
33
+ end
34
+ pointer.put_bytes offset, bytes, 0, size
35
+ end
36
+
37
+ # Create an unowned copy of the struct represented by val
38
+ def copy_from(val)
39
+ copy(from(val)).tap { |it| it && it.to_ptr.autorelease = false }
40
+ end
41
+
42
+ # Wrap an owned copy of the struct represented by val
43
+ def wrap_copy(val)
44
+ copy wrap(val)
45
+ end
46
+
47
+ # Create a copy of the struct represented by val
48
+ def copy(val)
49
+ return unless val
50
+ new.tap { |copy| copy_value_to_pointer(val, copy.to_ptr) }
51
+ end
52
+ end
53
+ end
@@ -3,6 +3,12 @@ require 'gir_ffi/boxed_base'
3
3
 
4
4
  module GirFFI
5
5
  # Base class for generated classes representing GLib unions.
6
- class UnionBase < BoxedBase
6
+ class UnionBase < ClassBase
7
+ extend FFI::DataConverter
8
+ extend GirFFI::StructLikeBase
9
+
10
+ def initialize
11
+ @struct = self.class::Struct.new
12
+ end
7
13
  end
8
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # Current GirFFI version
3
3
  module GirFFI
4
- VERSION = '0.9.5'.freeze
4
+ VERSION = '0.10.0.pre1'.freeze
5
5
  end
@@ -6,8 +6,11 @@ describe GLib::DestroyNotify do
6
6
  it 'removes the passed-in key from the callback store' do
7
7
  dummy_proc = 'some-callback'
8
8
  GirFFI::CallbackBase.store_callback dummy_proc
9
- user_data = GirFFI::InPointer.from_closure_data dummy_proc
9
+ GirFFI::CallbackBase::CALLBACKS[dummy_proc.object_id].wont_be_nil
10
+
11
+ user_data = GirFFI::ArgHelper.store dummy_proc
10
12
  GLib::DestroyNotify.default.call user_data
13
+
11
14
  GirFFI::CallbackBase::CALLBACKS[dummy_proc.object_id].must_be_nil
12
15
  end
13
16
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ require 'gir_ffi_test_helper'
3
+
4
+ require 'ffi-gobject'
5
+ describe GObject::ParamSpec do
6
+ describe '#ref' do
7
+ it 'increases the ref count' do
8
+ pspec = GObject.param_spec_boolean('foo', 'foo bar',
9
+ 'Boolean Foo Bar',
10
+ false,
11
+ readable: true, writable: true)
12
+
13
+ old = pspec.ref_count
14
+ pspec.ref
15
+ pspec.ref_count.must_equal old + 1
16
+ end
17
+ end
18
+ end
@@ -24,4 +24,21 @@ describe GirFFI::ArgHelper do
24
24
  GirFFI::ArgHelper.cast_from_pointer(:guint32, ptr).must_equal(0xffffffff)
25
25
  end
26
26
  end
27
+
28
+ describe '.store' do
29
+ describe 'when called with nil' do
30
+ it 'returns a null pointer' do
31
+ GirFFI::ArgHelper.store(nil).must_be :null?
32
+ end
33
+ end
34
+
35
+ describe 'when called with a string' do
36
+ it 'stores the string in GirFFI::ArgHelper::OBJECT_STORE' do
37
+ str = 'Foo'
38
+ ptr = GirFFI::ArgHelper.store(str)
39
+ result = GirFFI::ArgHelper::OBJECT_STORE.fetch(ptr)
40
+ result.must_equal str
41
+ end
42
+ end
43
+ end
27
44
  end