gir_ffi 0.7.8 → 0.7.9

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +16 -0
  3. data/README.md +24 -11
  4. data/TODO.md +10 -2
  5. data/gir_ffi.gemspec +2 -2
  6. data/lib/ffi-glib/array.rb +1 -1
  7. data/lib/ffi-glib/hash_table.rb +0 -4
  8. data/lib/ffi-gobject.rb +10 -6
  9. data/lib/ffi-gobject/object.rb +17 -0
  10. data/lib/ffi-gobject/ruby_closure.rb +1 -1
  11. data/lib/ffi-gobject/value.rb +28 -4
  12. data/lib/ffi-gobject_introspection.rb +4 -0
  13. data/lib/ffi-gobject_introspection/g_error.rb +2 -2
  14. data/lib/ffi-gobject_introspection/i_base_info.rb +1 -3
  15. data/lib/ffi-gobject_introspection/i_callable_info.rb +8 -0
  16. data/lib/ffi-gobject_introspection/i_registered_type_info.rb +2 -0
  17. data/lib/ffi-gobject_introspection/i_repository.rb +4 -4
  18. data/lib/ffi-gobject_introspection/lib.rb +57 -32
  19. data/lib/gir_ffi.rb +1 -1
  20. data/lib/gir_ffi/boxed_base.rb +40 -0
  21. data/lib/gir_ffi/builders/argument_builder.rb +11 -3
  22. data/lib/gir_ffi/builders/base_argument_builder.rb +4 -0
  23. data/lib/gir_ffi/builders/boxed_builder.rb +29 -0
  24. data/lib/gir_ffi/builders/callback_builder.rb +3 -1
  25. data/lib/gir_ffi/builders/callback_return_value_builder.rb +9 -1
  26. data/lib/gir_ffi/builders/field_builder.rb +68 -18
  27. data/lib/gir_ffi/builders/function_builder.rb +12 -2
  28. data/lib/gir_ffi/builders/mapping_method_builder.rb +7 -5
  29. data/lib/gir_ffi/builders/marshalling_method_builder.rb +1 -1
  30. data/lib/gir_ffi/builders/module_builder.rb +1 -1
  31. data/lib/gir_ffi/builders/registered_type_builder.rb +0 -9
  32. data/lib/gir_ffi/builders/return_value_builder.rb +0 -1
  33. data/lib/gir_ffi/builders/signal_closure_builder.rb +3 -1
  34. data/lib/gir_ffi/builders/struct_builder.rb +4 -16
  35. data/lib/gir_ffi/builders/union_builder.rb +2 -13
  36. data/lib/gir_ffi/builders/user_defined_builder.rb +6 -6
  37. data/lib/gir_ffi/builders/vfunc_argument_builder.rb +44 -0
  38. data/lib/gir_ffi/builders/vfunc_builder.rb +3 -1
  39. data/lib/gir_ffi/callback_base.rb +5 -2
  40. data/lib/gir_ffi/class_base.rb +6 -7
  41. data/lib/gir_ffi/enum_base.rb +5 -0
  42. data/lib/gir_ffi/ffi_ext/pointer.rb +1 -0
  43. data/lib/gir_ffi/field_argument_info.rb +4 -0
  44. data/lib/gir_ffi/in_out_pointer.rb +1 -1
  45. data/lib/gir_ffi/in_pointer.rb +2 -2
  46. data/lib/gir_ffi/info_ext/i_arg_info.rb +12 -2
  47. data/lib/gir_ffi/info_ext/i_callable_info.rb +1 -1
  48. data/lib/gir_ffi/info_ext/i_callback_info.rb +7 -2
  49. data/lib/gir_ffi/info_ext/i_field_info.rb +1 -1
  50. data/lib/gir_ffi/info_ext/i_function_info.rb +1 -1
  51. data/lib/gir_ffi/info_ext/i_registered_type_info.rb +7 -2
  52. data/lib/gir_ffi/info_ext/i_type_info.rb +21 -9
  53. data/lib/gir_ffi/info_ext/i_unresolved_info.rb +5 -0
  54. data/lib/gir_ffi/interface_base.rb +5 -0
  55. data/lib/gir_ffi/object_base.rb +5 -0
  56. data/lib/gir_ffi/receiver_argument_info.rb +5 -0
  57. data/lib/gir_ffi/registered_type_base.rb +5 -0
  58. data/lib/gir_ffi/return_value_info.rb +3 -1
  59. data/lib/gir_ffi/sized_array.rb +1 -1
  60. data/lib/gir_ffi/struct_base.rb +2 -24
  61. data/lib/gir_ffi/type_map.rb +5 -1
  62. data/lib/gir_ffi/union_base.rb +2 -2
  63. data/lib/gir_ffi/version.rb +1 -1
  64. data/lib/gir_ffi/zero_terminated.rb +1 -1
  65. data/test/base_test_helper.rb +6 -6
  66. data/test/ffi-glib/hash_table_test.rb +7 -7
  67. data/test/ffi-glib/iconv_test.rb +2 -3
  68. data/test/ffi-glib/main_loop_test.rb +2 -2
  69. data/test/ffi-gobject/gobject_test.rb +1 -1
  70. data/test/ffi-gobject/object_test.rb +5 -14
  71. data/test/ffi-gobject/value_test.rb +30 -6
  72. data/test/ffi-gobject_introspection/i_base_info_test.rb +6 -6
  73. data/test/ffi-gobject_introspection/i_repository_test.rb +2 -4
  74. data/test/gir_ffi/arg_helper_test.rb +1 -1
  75. data/test/gir_ffi/builder_test.rb +18 -12
  76. data/test/gir_ffi/builders/argument_builder_test.rb +2 -5
  77. data/test/gir_ffi/builders/callback_builder_test.rb +1 -1
  78. data/test/gir_ffi/builders/callback_return_value_builder_test.rb +11 -10
  79. data/test/gir_ffi/builders/field_builder_test.rb +0 -2
  80. data/test/gir_ffi/builders/function_builder_test.rb +156 -147
  81. data/test/gir_ffi/builders/interface_builder_test.rb +1 -1
  82. data/test/gir_ffi/builders/module_builder_test.rb +2 -2
  83. data/test/gir_ffi/builders/object_builder_test.rb +2 -2
  84. data/test/gir_ffi/builders/property_builder_test.rb +5 -5
  85. data/test/gir_ffi/builders/return_value_builder_test.rb +30 -30
  86. data/test/gir_ffi/builders/struct_builder_test.rb +14 -14
  87. data/test/gir_ffi/builders/user_defined_builder_test.rb +21 -22
  88. data/test/gir_ffi/builders/vfunc_builder_test.rb +57 -0
  89. data/test/gir_ffi/class_base_test.rb +8 -8
  90. data/test/gir_ffi/ffi_ext/pointer_test.rb +4 -4
  91. data/test/gir_ffi/g_type_test.rb +1 -1
  92. data/test/gir_ffi/in_pointer_test.rb +2 -2
  93. data/test/gir_ffi/info_ext/i_callable_info_test.rb +3 -3
  94. data/test/gir_ffi/info_ext/i_callback_info_test.rb +2 -2
  95. data/test/gir_ffi/info_ext/i_field_info_test.rb +8 -8
  96. data/test/gir_ffi/info_ext/i_function_info_test.rb +13 -13
  97. data/test/gir_ffi/info_ext/i_type_info_test.rb +131 -132
  98. data/test/gir_ffi/info_ext/i_unresolved_info_test.rb +2 -2
  99. data/test/gir_ffi/info_ext/safe_constant_name_test.rb +2 -2
  100. data/test/gir_ffi/info_ext/safe_function_name_test.rb +2 -2
  101. data/test/gir_ffi/interface_base_test.rb +3 -3
  102. data/test/gir_ffi/object_base_test.rb +3 -3
  103. data/test/gir_ffi/sized_array_test.rb +2 -2
  104. data/test/gir_ffi/type_map_test.rb +3 -3
  105. data/test/gir_ffi/unintrospectable_type_info_test.rb +14 -14
  106. data/test/gir_ffi/user_defined_property_info_test.rb +1 -1
  107. data/test/gir_ffi/user_defined_type_info_test.rb +25 -12
  108. data/test/gir_ffi/zero_terminated_test.rb +0 -1
  109. data/test/gir_ffi_test.rb +3 -3
  110. data/test/gir_ffi_test_helper.rb +4 -0
  111. data/test/integration/generated_gimarshallingtests_test.rb +31 -25
  112. data/test/integration/generated_gio_test.rb +1 -1
  113. data/test/integration/generated_gobject_test.rb +1 -1
  114. data/test/integration/generated_regress_test.rb +18 -22
  115. metadata +11 -8
@@ -29,7 +29,7 @@ module GirFFI
29
29
  info = UserDefinedTypeInfo.new(klass, &block)
30
30
  Builders::UserDefinedBuilder.new(info).build_class
31
31
 
32
- klass.get_gtype
32
+ klass.gtype
33
33
  end
34
34
  end
35
35
 
@@ -0,0 +1,40 @@
1
+ require 'gir_ffi/class_base'
2
+
3
+ module GirFFI
4
+ # Base class for generated classes representing boxed types.
5
+ class BoxedBase < ClassBase
6
+ extend FFI::DataConverter
7
+
8
+ def self.native_type
9
+ FFI::Type::Struct.new(self::Struct)
10
+ end
11
+
12
+ # @deprecated Use #to_ffi_type instead. Will be removed in 0.8.0.
13
+ def self.to_ffitype
14
+ to_ffi_type
15
+ end
16
+
17
+ def self.to_ffi_type
18
+ self
19
+ end
20
+
21
+ def self.to_native value, _context
22
+ value.struct
23
+ end
24
+
25
+ def self.get_value_from_pointer pointer
26
+ pointer.to_ptr
27
+ end
28
+
29
+ def self.copy_value_to_pointer value, pointer, offset = 0
30
+ size = self::Struct.size
31
+ pointer.put_bytes offset, value.to_ptr.read_bytes(size), 0, size
32
+ end
33
+
34
+ def self._allocate
35
+ obj = _real_new
36
+ obj.instance_variable_set :@struct, self::Struct.new
37
+ obj
38
+ end
39
+ end
40
+ end
@@ -143,11 +143,19 @@ module GirFFI
143
143
  if skipped?
144
144
  NullConvertor.new('0')
145
145
  elsif closure?
146
- ClosureToPointerConvertor.new(name)
146
+ ClosureToPointerConvertor.new(pre_convertor_argument)
147
147
  elsif @type_info.needs_ruby_to_c_conversion_for_functions?
148
- RubyToCConvertor.new(@type_info, name)
148
+ RubyToCConvertor.new(@type_info, pre_convertor_argument)
149
149
  else
150
- NullConvertor.new(name)
150
+ NullConvertor.new(pre_convertor_argument)
151
+ end
152
+ end
153
+
154
+ def pre_convertor_argument
155
+ if ownership_transfer == :everything && specialized_type_tag == :object
156
+ "#{name}.ref"
157
+ else
158
+ name
151
159
  end
152
160
  end
153
161
  end
@@ -60,6 +60,10 @@ module GirFFI
60
60
  type_info.array_length
61
61
  end
62
62
 
63
+ def ownership_transfer
64
+ arginfo.ownership_transfer
65
+ end
66
+
63
67
  def safe name
64
68
  if KEYWORDS.include? name
65
69
  "#{name}_"
@@ -0,0 +1,29 @@
1
+ require 'gir_ffi/builders/registered_type_builder'
2
+ require 'gir_ffi/builders/with_layout'
3
+
4
+ module GirFFI
5
+ module Builders
6
+ # Implements the creation of a class representing boxed types.
7
+ class BoxedBuilder < RegisteredTypeBuilder
8
+ include WithLayout
9
+
10
+ private
11
+
12
+ def setup_class
13
+ setup_layout
14
+ setup_constants
15
+ stub_methods
16
+ setup_field_accessors
17
+ provide_constructor
18
+ end
19
+
20
+ def provide_constructor
21
+ return if info.find_method 'new'
22
+
23
+ (class << klass; self; end).class_eval {
24
+ alias_method :new, :_allocate
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -25,7 +25,9 @@ module GirFFI
25
25
  end
26
26
 
27
27
  def mapping_method_definition
28
- return_value_info = ReturnValueInfo.new info.return_type
28
+ return_value_info = ReturnValueInfo.new(info.return_type,
29
+ info.caller_owns,
30
+ info.skip_return?)
29
31
  MappingMethodBuilder.for_callback(info.args,
30
32
  return_value_info).method_definition
31
33
  end
@@ -45,7 +45,15 @@ module GirFFI
45
45
  end
46
46
 
47
47
  def post_convertor
48
- @post_convertor ||= RubyToCConvertor.new(type_info, capture_variable_name)
48
+ @post_convertor ||= RubyToCConvertor.new(type_info, post_convertor_argument)
49
+ end
50
+
51
+ def post_convertor_argument
52
+ if ownership_transfer == :everything && specialized_type_tag == :object
53
+ "#{capture_variable_name}.ref"
54
+ else
55
+ capture_variable_name
56
+ end
49
57
  end
50
58
 
51
59
  def void_return_value?
@@ -7,6 +7,59 @@ module GirFFI
7
7
  module Builders
8
8
  # Creates field getter and setter code for a given IFieldInfo.
9
9
  class FieldBuilder
10
+ # Builder for field getters
11
+ class GetterBuilder
12
+ def initialize field_builder, return_value_builder
13
+ @field_builder = field_builder
14
+ @return_value_builder = return_value_builder
15
+ end
16
+
17
+ def singleton_method?
18
+ false
19
+ end
20
+
21
+ def method_name
22
+ @field_builder.field_name
23
+ end
24
+
25
+ def method_arguments
26
+ []
27
+ end
28
+
29
+ def preparation
30
+ [
31
+ "#{field_ptr} = @struct.to_ptr + #{field_offset}",
32
+ "#{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag}, #{field_ptr})"
33
+ ]
34
+ end
35
+
36
+ def invocation
37
+ "#{typed_ptr}.to_value"
38
+ end
39
+
40
+ def result
41
+ [@return_value_builder.return_value_name]
42
+ end
43
+
44
+ private
45
+
46
+ def field_ptr
47
+ @field_ptr ||= @return_value_builder.new_variable
48
+ end
49
+
50
+ def typed_ptr
51
+ @typed_ptr ||= @return_value_builder.new_variable
52
+ end
53
+
54
+ def field_offset
55
+ @field_builder.field_offset
56
+ end
57
+
58
+ def field_type_tag
59
+ @field_builder.field_type_tag
60
+ end
61
+ end
62
+
10
63
  attr_reader :info
11
64
 
12
65
  def initialize field_info
@@ -31,20 +84,9 @@ module GirFFI
31
84
  end
32
85
 
33
86
  def getter_def
34
- builder = return_value_builder
35
-
36
- field_ptr = builder.new_variable
37
- typed_ptr = builder.new_variable
38
-
39
- <<-CODE.reset_indentation
40
- def #{info.name}
41
- #{field_ptr} = @struct.to_ptr + #{info.offset}
42
- #{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag_or_class}, #{field_ptr})
43
- #{builder.capture_variable_name} = #{typed_ptr}.to_value
44
- #{builder.post_conversion.join("\n")}
45
- #{builder.return_value_name}
46
- end
47
- CODE
87
+ argument_builders = ArgumentBuilderCollection.new(return_value_builder, [])
88
+ getter_builder = GetterBuilder.new(self, return_value_builder)
89
+ MethodTemplate.new(getter_builder, argument_builders).method_definition
48
90
  end
49
91
 
50
92
  def setter_def
@@ -56,19 +98,27 @@ module GirFFI
56
98
  <<-CODE.reset_indentation
57
99
  def #{info.name}= #{builder.method_argument_name}
58
100
  #{field_ptr} = @struct.to_ptr + #{info.offset}
59
- #{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag_or_class}, #{field_ptr})
101
+ #{typed_ptr} = GirFFI::InOutPointer.new(#{field_type_tag}, #{field_ptr})
60
102
  #{builder.pre_conversion.join("\n ")}
61
103
  #{typed_ptr}.set_value #{builder.call_argument_name}
62
104
  end
63
105
  CODE
64
106
  end
65
107
 
66
- private
108
+ def field_name
109
+ @field_name ||= info.name
110
+ end
67
111
 
68
- def field_type_tag_or_class
69
- @field_type_tag_or_class ||= info.field_type.tag_or_class.inspect
112
+ def field_offset
113
+ @field_offset ||= info.offset
70
114
  end
71
115
 
116
+ def field_type_tag
117
+ @field_type_tag ||= info.field_type.tag_or_class.inspect
118
+ end
119
+
120
+ private
121
+
72
122
  def container_class
73
123
  @container_class ||= container_module.const_get(container_info.safe_name)
74
124
  end
@@ -15,7 +15,9 @@ module GirFFI
15
15
  @info = info
16
16
  vargen = GirFFI::VariableNameGenerator.new
17
17
  @argument_builders = @info.args.map { |arg| ArgumentBuilder.new vargen, arg }
18
- return_value_info = ReturnValueInfo.new(@info.return_type, @info.skip_return?)
18
+ return_value_info = ReturnValueInfo.new(@info.return_type,
19
+ @info.caller_owns,
20
+ @info.skip_return?)
19
21
  @return_value_builder = ReturnValueBuilder.new(vargen,
20
22
  return_value_info,
21
23
  @info.constructor?)
@@ -71,9 +73,17 @@ module GirFFI
71
73
 
72
74
  def function_call_arguments
73
75
  ca = @argument_builder_collection.call_argument_names
74
- ca.unshift 'self' if @info.method?
76
+ ca.unshift receiver_call_argument if @info.method?
75
77
  ca
76
78
  end
79
+
80
+ def receiver_call_argument
81
+ if @info.instance_ownership_transfer == :everything
82
+ 'self.ref'
83
+ else
84
+ 'self'
85
+ end
86
+ end
77
87
  end
78
88
  end
79
89
  end
@@ -1,24 +1,26 @@
1
1
  require 'gir_ffi/variable_name_generator'
2
2
  require 'gir_ffi/builders/callback_argument_builder'
3
+ require 'gir_ffi/builders/vfunc_argument_builder'
3
4
  require 'gir_ffi/builders/callback_return_value_builder'
4
5
  require 'gir_ffi/builders/argument_builder_collection'
5
6
  require 'gir_ffi/builders/method_template'
6
7
 
7
8
  module GirFFI
8
9
  module Builders
9
- # Implements the creation mapping method for a callback or signal
10
+ # Implements the creation mapping method for a callback or vfunc
10
11
  # handler. This method converts arguments from C to Ruby, and the
11
12
  # result from Ruby to C.
12
13
  class MappingMethodBuilder
13
14
  def self.for_callback argument_infos, return_value_info
14
- new argument_infos, return_value_info
15
+ new argument_infos, return_value_info, CallbackArgumentBuilder
15
16
  end
16
17
 
17
18
  def self.for_vfunc receiver_info, argument_infos, return_value_info
18
- new receiver_info, argument_infos, return_value_info
19
+ new receiver_info, argument_infos, return_value_info, VFuncArgumentBuilder
19
20
  end
20
21
 
21
- def initialize receiver_info = nil, argument_infos, return_value_info
22
+ def initialize receiver_info = nil, argument_infos, return_value_info, builder_class
23
+ @argument_builder_class = builder_class
22
24
  receiver_builder = make_argument_builder receiver_info if receiver_info
23
25
  argument_builders = argument_infos.map { |info| make_argument_builder info }
24
26
  return_value_builder =
@@ -74,7 +76,7 @@ module GirFFI
74
76
  end
75
77
 
76
78
  def make_argument_builder argument_info
77
- CallbackArgumentBuilder.new variable_generator, argument_info
79
+ @argument_builder_class.new variable_generator, argument_info
78
80
  end
79
81
  end
80
82
  end
@@ -6,7 +6,7 @@ require 'gir_ffi/builders/method_template'
6
6
 
7
7
  module GirFFI
8
8
  module Builders
9
- # Implements the creation mapping method for a callback or signal
9
+ # Implements the creation mapping method for a signal
10
10
  # handler. This method converts arguments from C to Ruby, and the
11
11
  # result from Ruby to C.
12
12
  class MarshallingMethodBuilder
@@ -35,7 +35,7 @@ module GirFFI
35
35
  info = gir.find_by_name @namespace, classname.to_s
36
36
  unless info
37
37
  raise NameError,
38
- "Class #{classname} not found in namespace #{@namespace}"
38
+ "Class #{classname} not found in namespace #{@namespace}"
39
39
  end
40
40
  Builder.build_class info
41
41
  end
@@ -52,15 +52,6 @@ module GirFFI
52
52
  super
53
53
  end
54
54
 
55
- # FIXME: Only used in some of the subclases. Make mixin?
56
- def provide_constructor
57
- return if info.find_method 'new'
58
-
59
- (class << klass; self; end).class_eval {
60
- alias_method :new, :_allocate
61
- }
62
- end
63
-
64
55
  def parent_info
65
56
  nil
66
57
  end
@@ -33,7 +33,6 @@ module GirFFI
33
33
  end
34
34
 
35
35
  def post_conversion
36
- # TODO: Avoid conditional by using NullConvertor
37
36
  if has_post_conversion?
38
37
  ["#{post_converted_name} = #{post_convertor.conversion}"]
39
38
  else
@@ -20,7 +20,9 @@ module GirFFI
20
20
 
21
21
  container_type_info = ReceiverTypeInfo.new(container_info)
22
22
  receiver_info = ReceiverArgumentInfo.new(container_type_info)
23
- return_value_info = ReturnValueInfo.new info.return_type
23
+ return_value_info = ReturnValueInfo.new(info.return_type,
24
+ info.caller_owns,
25
+ info.skip_return?)
24
26
 
25
27
  MarshallingMethodBuilder.for_signal(receiver_info,
26
28
  arg_infos,
@@ -1,28 +1,16 @@
1
- require 'gir_ffi/builders/registered_type_builder'
2
- require 'gir_ffi/builders/with_layout'
1
+ require 'gir_ffi/builders/boxed_builder'
3
2
  require 'gir_ffi/struct_base'
4
3
 
5
4
  module GirFFI
6
5
  module Builders
7
6
  # Implements the creation of a class representing a Struct.
8
- class StructBuilder < RegisteredTypeBuilder
9
- include WithLayout
10
-
11
- private
12
-
13
- def setup_class
14
- setup_layout
15
- setup_constants
16
- stub_methods
17
- setup_field_accessors
18
- provide_constructor
19
- end
20
-
21
- # FIXME: Private method only in subclass
7
+ class StructBuilder < BoxedBuilder
22
8
  def layout_superclass
23
9
  FFI::Struct
24
10
  end
25
11
 
12
+ private
13
+
26
14
  def superclass
27
15
  StructBase
28
16
  end
@@ -1,28 +1,17 @@
1
- require 'gir_ffi/builders/registered_type_builder'
2
- require 'gir_ffi/builders/with_layout'
1
+ require 'gir_ffi/builders/boxed_builder'
3
2
  require 'gir_ffi/union_base'
4
3
 
5
4
  module GirFFI
6
5
  module Builders
7
6
  # Implements the creation of a class representing union type. The
8
7
  # class will have a nested FFI::Union class to represent its C union.
9
- class UnionBuilder < RegisteredTypeBuilder
10
- include WithLayout
11
-
8
+ class UnionBuilder < BoxedBuilder
12
9
  def layout_superclass
13
10
  FFI::Union
14
11
  end
15
12
 
16
13
  private
17
14
 
18
- def setup_class
19
- setup_layout
20
- setup_constants
21
- stub_methods
22
- setup_field_accessors
23
- provide_constructor
24
- end
25
-
26
15
  def superclass
27
16
  UnionBase
28
17
  end