gir_ffi 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/History.txt +14 -0
  2. data/TODO.rdoc +23 -5
  3. data/lib/ffi-glib/array.rb +14 -15
  4. data/lib/ffi-glib/container_class_methods.rb +0 -1
  5. data/lib/ffi-glib/hash_table.rb +3 -4
  6. data/lib/ffi-glib/ptr_array.rb +12 -4
  7. data/lib/ffi-glib/sized_array.rb +27 -7
  8. data/lib/ffi-gobject.rb +14 -15
  9. data/lib/ffi-gobject/closure.rb +1 -1
  10. data/lib/ffi-gobject/object.rb +40 -15
  11. data/lib/ffi-gobject/ruby_closure.rb +0 -1
  12. data/lib/ffi-gobject/value.rb +45 -21
  13. data/lib/ffi-gobject_introspection/i_arg_info.rb +4 -0
  14. data/lib/ffi-gobject_introspection/i_base_info.rb +42 -2
  15. data/lib/ffi-gobject_introspection/i_callable_info.rb +8 -0
  16. data/lib/ffi-gobject_introspection/i_enum_info.rb +1 -4
  17. data/lib/ffi-gobject_introspection/i_interface_info.rb +1 -0
  18. data/lib/ffi-gobject_introspection/i_object_info.rb +2 -0
  19. data/lib/ffi-gobject_introspection/i_repository.rb +2 -3
  20. data/lib/ffi-gobject_introspection/i_struct_info.rb +3 -8
  21. data/lib/ffi-gobject_introspection/lib.rb +3 -0
  22. data/lib/gir_ffi-base.rb +3 -1
  23. data/lib/gir_ffi-base/gir_ffi/struct.rb +27 -0
  24. data/lib/gir_ffi-base/glib/boolean.rb +13 -1
  25. data/lib/gir_ffi-base/gobject.rb +7 -0
  26. data/lib/gir_ffi-base/gobject/lib.rb +0 -2
  27. data/lib/gir_ffi.rb +1 -3
  28. data/lib/gir_ffi/arg_helper.rb +4 -85
  29. data/lib/gir_ffi/builder.rb +5 -5
  30. data/lib/gir_ffi/builder_helper.rb +7 -0
  31. data/lib/gir_ffi/builders/argument_builder.rb +132 -0
  32. data/lib/gir_ffi/{base_argument_builder.rb → builders/base_argument_builder.rb} +32 -41
  33. data/lib/gir_ffi/builders/base_type_builder.rb +47 -0
  34. data/lib/gir_ffi/builders/callback_builder.rb +38 -0
  35. data/lib/gir_ffi/builders/constant_builder.rb +18 -0
  36. data/lib/gir_ffi/builders/enum_builder.rb +62 -0
  37. data/lib/gir_ffi/builders/error_argument_builder.rb +18 -0
  38. data/lib/gir_ffi/builders/field_builder.rb +94 -0
  39. data/lib/gir_ffi/builders/function_builder.rb +123 -0
  40. data/lib/gir_ffi/builders/interface_builder.rb +29 -0
  41. data/lib/gir_ffi/builders/mapping_method_builder.rb +88 -0
  42. data/lib/gir_ffi/builders/module_builder.rb +124 -0
  43. data/lib/gir_ffi/{null_argument_builder.rb → builders/null_argument_builder.rb} +0 -0
  44. data/lib/gir_ffi/builders/null_builder.rb +11 -0
  45. data/lib/gir_ffi/builders/object_builder.rb +123 -0
  46. data/lib/gir_ffi/{builder/property.rb → builders/property_builder.rb} +0 -0
  47. data/lib/gir_ffi/builders/registered_type_builder.rb +50 -0
  48. data/lib/gir_ffi/builders/return_value_builder.rb +68 -0
  49. data/lib/gir_ffi/builders/signal_builder.rb +91 -0
  50. data/lib/gir_ffi/builders/struct_builder.rb +35 -0
  51. data/lib/gir_ffi/builders/type_builder.rb +40 -0
  52. data/lib/gir_ffi/builders/unintrospectable_builder.rb +35 -0
  53. data/lib/gir_ffi/builders/union_builder.rb +34 -0
  54. data/lib/gir_ffi/builders/user_defined_builder.rb +103 -0
  55. data/lib/gir_ffi/builders/with_layout.rb +55 -0
  56. data/lib/gir_ffi/builders/with_methods.rb +44 -0
  57. data/lib/gir_ffi/callback_base.rb +31 -0
  58. data/lib/gir_ffi/class_base.rb +16 -10
  59. data/lib/gir_ffi/enum_base.rb +8 -4
  60. data/lib/gir_ffi/ffi_ext/pointer.rb +19 -2
  61. data/lib/gir_ffi/in_out_pointer.rb +38 -39
  62. data/lib/gir_ffi/in_pointer.rb +33 -18
  63. data/lib/gir_ffi/info_ext.rb +0 -4
  64. data/lib/gir_ffi/info_ext/i_arg_info.rb +0 -18
  65. data/lib/gir_ffi/info_ext/i_callable_info.rb +2 -1
  66. data/lib/gir_ffi/info_ext/i_registered_type_info.rb +6 -8
  67. data/lib/gir_ffi/info_ext/i_signal_info.rb +6 -21
  68. data/lib/gir_ffi/info_ext/i_type_info.rb +54 -29
  69. data/lib/gir_ffi/info_ext/safe_constant_name.rb +8 -1
  70. data/lib/gir_ffi/interface_base.rb +1 -1
  71. data/lib/gir_ffi/module_base.rb +5 -1
  72. data/lib/gir_ffi/object_base.rb +5 -1
  73. data/lib/gir_ffi/setter_argument_info.rb +4 -0
  74. data/lib/gir_ffi/signal_base.rb +21 -0
  75. data/lib/gir_ffi/struct_base.rb +24 -0
  76. data/lib/gir_ffi/type_base.rb +11 -0
  77. data/lib/gir_ffi/type_map.rb +4 -2
  78. data/lib/gir_ffi/union_base.rb +24 -0
  79. data/lib/gir_ffi/version.rb +1 -1
  80. data/tasks/test.rake +73 -7
  81. data/test/base_test_helper.rb +3 -19
  82. data/test/ffi-glib/array_test.rb +6 -0
  83. data/test/ffi-glib/ptr_array_test.rb +13 -0
  84. data/test/ffi-glib/ruby_closure_test.rb +7 -7
  85. data/test/ffi-glib/sized_array_test.rb +2 -2
  86. data/test/ffi-gobject/gobject_test.rb +3 -12
  87. data/test/ffi-gobject/object_test.rb +33 -2
  88. data/test/ffi-gobject/value_test.rb +114 -1
  89. data/test/ffi-gobject_introspection/i_enum_info_test.rb +2 -2
  90. data/test/ffi-gobject_introspection/i_object_info_test.rb +3 -3
  91. data/test/ffi-gobject_introspection/i_repository_test.rb +26 -21
  92. data/test/ffi-gobject_test.rb +14 -14
  93. data/test/gir_ffi-base/glib/boolean_test.rb +6 -0
  94. data/test/gir_ffi/arg_helper_test.rb +2 -122
  95. data/test/gir_ffi/builder_test.rb +67 -204
  96. data/test/gir_ffi/{argument_builder_test.rb → builders/argument_builder_test.rb} +230 -108
  97. data/test/gir_ffi/builders/base_argument_builder_test.rb +5 -0
  98. data/test/gir_ffi/builders/callback_builder_test.rb +50 -0
  99. data/test/gir_ffi/builders/constant_builder_test.rb +4 -0
  100. data/test/gir_ffi/{builder/type/enum_test.rb → builders/enum_builder_test.rb} +2 -3
  101. data/test/gir_ffi/builders/field_builder_test.rb +94 -0
  102. data/test/gir_ffi/{function_builder_test.rb → builders/function_builder_test.rb} +43 -24
  103. data/test/gir_ffi/{builder/type/interface_test.rb → builders/interface_builder_test.rb} +2 -2
  104. data/test/gir_ffi/{builder/module_test.rb → builders/module_builder_test.rb} +12 -13
  105. data/test/gir_ffi/{builder/type/object_test.rb → builders/object_builder_test.rb} +9 -9
  106. data/test/gir_ffi/{return_value_builder_test.rb → builders/return_value_builder_test.rb} +94 -58
  107. data/test/gir_ffi/builders/signal_builder_test.rb +62 -0
  108. data/test/gir_ffi/{builder/type/struct_test.rb → builders/struct_builder_test.rb} +36 -19
  109. data/test/gir_ffi/{builder/type/unintrospectable_test.rb → builders/unintrospectable_builder_test.rb} +3 -3
  110. data/test/gir_ffi/builders/union_builder_test.rb +29 -0
  111. data/test/gir_ffi/{builder/type/user_defined_test.rb → builders/user_defined_builder_test.rb} +2 -2
  112. data/test/gir_ffi/callback_base_test.rb +11 -0
  113. data/test/gir_ffi/class_base_test.rb +22 -22
  114. data/test/gir_ffi/ffi_ext/pointer_test.rb +18 -0
  115. data/test/gir_ffi/in_out_pointer_test.rb +0 -7
  116. data/test/gir_ffi/in_pointer_test.rb +27 -3
  117. data/test/gir_ffi/info_ext/i_signal_info_test.rb +16 -44
  118. data/test/gir_ffi/info_ext/i_type_info_test.rb +315 -74
  119. data/test/gir_ffi/info_ext/safe_constant_name_test.rb +6 -0
  120. data/test/gir_ffi/interface_base_test.rb +3 -5
  121. data/test/gir_ffi/object_base_test.rb +10 -6
  122. data/test/gir_ffi/type_map_test.rb +2 -2
  123. data/test/gir_ffi/unintrospectable_type_info_test.rb +2 -2
  124. data/test/gir_ffi_test_helper.rb +12 -4
  125. data/test/integration/generated_gimarshallingtests_test.rb +436 -76
  126. data/test/integration/generated_gio_test.rb +5 -11
  127. data/test/integration/generated_gobject_test.rb +8 -0
  128. data/test/integration/generated_regress_test.rb +755 -309
  129. data/test/integration/generated_secret_test.rb +2 -1
  130. metadata +73 -72
  131. data/lib/ffi-gobject/ruby_style.rb +0 -23
  132. data/lib/gir_ffi/argument_builder.rb +0 -154
  133. data/lib/gir_ffi/builder/field.rb +0 -60
  134. data/lib/gir_ffi/builder/module.rb +0 -127
  135. data/lib/gir_ffi/builder/type.rb +0 -39
  136. data/lib/gir_ffi/builder/type/base.rb +0 -48
  137. data/lib/gir_ffi/builder/type/callback.rb +0 -30
  138. data/lib/gir_ffi/builder/type/constant.rb +0 -22
  139. data/lib/gir_ffi/builder/type/enum.rb +0 -66
  140. data/lib/gir_ffi/builder/type/interface.rb +0 -33
  141. data/lib/gir_ffi/builder/type/object.rb +0 -134
  142. data/lib/gir_ffi/builder/type/registered_type.rb +0 -62
  143. data/lib/gir_ffi/builder/type/struct.rb +0 -34
  144. data/lib/gir_ffi/builder/type/unintrospectable.rb +0 -39
  145. data/lib/gir_ffi/builder/type/union.rb +0 -34
  146. data/lib/gir_ffi/builder/type/user_defined.rb +0 -107
  147. data/lib/gir_ffi/builder/type/with_layout.rb +0 -62
  148. data/lib/gir_ffi/builder/type/with_methods.rb +0 -64
  149. data/lib/gir_ffi/callback.rb +0 -72
  150. data/lib/gir_ffi/callback_helper.rb +0 -11
  151. data/lib/gir_ffi/error_argument_builder.rb +0 -17
  152. data/lib/gir_ffi/function_builder.rb +0 -112
  153. data/lib/gir_ffi/info_ext/i_enum_info.rb +0 -11
  154. data/lib/gir_ffi/info_ext/i_object_info.rb +0 -11
  155. data/lib/gir_ffi/info_ext/i_struct_info.rb +0 -11
  156. data/lib/gir_ffi/info_ext/i_union_info.rb +0 -12
  157. data/lib/gir_ffi/return_value_builder.rb +0 -81
  158. data/test/ffi-gobject/ruby_style_test.rb +0 -38
  159. data/test/gir_ffi/base_argument_builder_test.rb +0 -13
  160. data/test/gir_ffi/builder/type/callback_test.rb +0 -6
  161. data/test/gir_ffi/builder/type/constant_test.rb +0 -4
  162. data/test/gir_ffi/builder/type/union_test.rb +0 -12
  163. data/test/gir_ffi/callback_helper_test.rb +0 -10
  164. data/test/gir_ffi/callback_test.rb +0 -49
  165. data/test/gir_ffi/info_ext/i_arg_info_test.rb +0 -39
  166. data/test/gir_ffi/info_ext/i_object_info_test.rb +0 -14
@@ -0,0 +1,55 @@
1
+ require 'gir_ffi/builders/field_builder'
2
+
3
+ module GirFFI
4
+ module Builders
5
+ # Implements the creation of classes representing types with layout,
6
+ # i.e., :union, :struct, :object.
7
+ # Note: This module depends on the additional inclusion of
8
+ # WithMethods.
9
+ module WithLayout
10
+ def layout_specification
11
+ spec = base_layout_specification
12
+ if spec.empty?
13
+ dummy_layout_specification
14
+ else
15
+ spec
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def setup_layout
22
+ spec = layout_specification
23
+ @structklass.class_eval { layout(*spec) }
24
+ end
25
+
26
+ def dummy_layout_specification
27
+ if parent
28
+ [:parent, superclass.const_get(:Struct), 0]
29
+ else
30
+ [:dummy, :char, 0]
31
+ end
32
+ end
33
+
34
+ def base_layout_specification
35
+ fields.map { |finfo| finfo.layout_specification }.flatten(1)
36
+ end
37
+
38
+ def setup_accessors_for_field_info finfo
39
+ FieldBuilder.new(finfo).build
40
+ end
41
+
42
+ def setup_field_accessors
43
+ fields.each do |finfo|
44
+ setup_accessors_for_field_info finfo
45
+ end
46
+ end
47
+
48
+ def instantiate_class
49
+ @klass = get_or_define_class namespace_module, @classname, superclass
50
+ @structklass = get_or_define_class @klass, :Struct, layout_superclass
51
+ setup_class unless already_set_up
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,44 @@
1
+ require 'gir_ffi/method_stubber'
2
+
3
+ module GirFFI
4
+ module Builders
5
+ # Implements method creation for types such as, :union, :struct,
6
+ # :object, :interface.
7
+ module WithMethods
8
+ def setup_method method
9
+ go = info.find_method method
10
+ attach_and_define_method method, go, meta_class
11
+ end
12
+
13
+ def setup_instance_method method
14
+ go = info.find_instance_method method
15
+ attach_and_define_method method, go, build_class
16
+ end
17
+
18
+ private
19
+
20
+ def meta_class
21
+ klass = build_class
22
+ return (class << klass; self; end)
23
+ end
24
+
25
+ def function_definition go
26
+ FunctionBuilder.new(go).generate
27
+ end
28
+
29
+ def attach_and_define_method method, go, modul
30
+ return false if go.nil?
31
+ Builder.attach_ffi_function lib, go
32
+ modul.class_eval { remove_method method }
33
+ build_class.class_eval function_definition(go)
34
+ true
35
+ end
36
+
37
+ def stub_methods
38
+ info.get_methods.each do |minfo|
39
+ @klass.class_eval MethodStubber.new(minfo).method_stub
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ require 'gir_ffi/type_base'
2
+
3
+ module GirFFI
4
+ module CallbackBase
5
+ CALLBACKS = []
6
+
7
+ def store_callback prc
8
+ CALLBACKS << prc
9
+ end
10
+
11
+ def self.store_callback prc
12
+ CALLBACKS << prc
13
+ end
14
+
15
+ # Create Callback from a Proc. Makes sure arguments are properly wrapped,
16
+ # and the callback is stored to prevent garbage collection.
17
+ def from prc
18
+ wrap_in_callback_args_mapper(prc).tap do |cb|
19
+ store_callback cb
20
+ end
21
+ end
22
+
23
+ def wrap_in_callback_args_mapper prc
24
+ return prc if FFI::Function === prc
25
+ return nil if prc.nil?
26
+ return Proc.new do |*args|
27
+ call_with_argument_mapping(prc, *args)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,13 +1,19 @@
1
1
  require 'forwardable'
2
+ require 'gir_ffi/builders/null_builder'
3
+ require 'gir_ffi/type_base'
2
4
 
3
5
  module GirFFI
4
6
  # Base class for all generated classes. Contains code for dealing with
5
7
  # the generated Struct classes.
6
8
  class ClassBase
9
+ extend TypeBase
10
+
7
11
  # TODO: Make separate base for :struct, :union, :object.
8
12
  extend Forwardable
9
13
  def_delegators :@struct, :to_ptr
10
14
 
15
+ GIR_FFI_BUILDER = NullBuilder.new
16
+
11
17
  def setup_and_call method, *arguments, &block
12
18
  result = self.class.ancestors.any? do |klass|
13
19
  klass.respond_to?(:setup_instance_method) &&
@@ -21,8 +27,16 @@ module GirFFI
21
27
  self.send method, *arguments, &block
22
28
  end
23
29
 
24
- def ==(other)
25
- other.is_a?(self.class) && self.to_ptr == other.to_ptr
30
+ if RUBY_PLATFORM == 'java'
31
+ # FIXME: JRuby should fix FFI::MemoryPointer#== to return true for
32
+ # equivalent FFI::Pointer.
33
+ def ==(other)
34
+ other.class == self.class && self.to_ptr.address == other.to_ptr.address
35
+ end
36
+ else
37
+ def ==(other)
38
+ other.class == self.class && self.to_ptr == other.to_ptr
39
+ end
26
40
  end
27
41
 
28
42
  def self.setup_and_call method, *arguments, &block
@@ -39,14 +53,6 @@ module GirFFI
39
53
  end
40
54
 
41
55
  class << self
42
- def gir_info
43
- self.const_get :GIR_INFO
44
- end
45
-
46
- def gir_ffi_builder
47
- self.const_get :GIR_FFI_BUILDER
48
- end
49
-
50
56
  def to_ffitype
51
57
  self::Struct
52
58
  end
@@ -1,9 +1,17 @@
1
+ require 'gir_ffi/type_base'
2
+
1
3
  module GirFFI
2
4
  module EnumBase
5
+ include TypeBase
6
+ # TODO: Make this a DataConverter
3
7
  def [](arg)
4
8
  self::Enum[arg]
5
9
  end
6
10
 
11
+ def wrap arg
12
+ self[arg]
13
+ end
14
+
7
15
  def to_native *args
8
16
  self::Enum.to_native(*args)
9
17
  end
@@ -18,10 +26,6 @@ module GirFFI
18
26
  self.send method, *arguments, &block
19
27
  end
20
28
 
21
- def gir_ffi_builder
22
- self.const_get :GIR_FFI_BUILDER
23
- end
24
-
25
29
  def to_ffitype
26
30
  self::Enum
27
31
  end
@@ -10,11 +10,28 @@ module GirFFI
10
10
  end
11
11
 
12
12
  def to_object
13
- # TODO: Move implementation here.
14
- ArgHelper.object_pointer_to_object self
13
+ gtype = GObject.type_from_instance_pointer self
14
+ wrap_by_gtype gtype
15
+ end
16
+
17
+ def wrap_by_gtype gtype
18
+ return nil if self.null?
19
+ klass = Builder.build_by_gtype gtype
20
+ klass.direct_wrap self
21
+ end
22
+
23
+ if RUBY_VERSION < "1.9"
24
+ def to_utf8
25
+ null? ? nil : read_string
26
+ end
27
+ else
28
+ def to_utf8
29
+ null? ? nil : read_string.force_encoding("utf-8")
30
+ end
15
31
  end
16
32
  end
17
33
  end
18
34
  end
19
35
 
36
+ # TODO: Move use to InPointer and InOutPointer?
20
37
  FFI::Pointer.send :include, GirFFI::FFIExt::Pointer
@@ -15,52 +15,61 @@ module GirFFI
15
15
 
16
16
  private :initialize
17
17
 
18
- # TODO: Rename to get_value
18
+ # TODO: Create type classes that extract values from pointers.
19
19
  def to_value
20
20
  case value_ffi_type
21
21
  when Class
22
- to_ptr
22
+ value_ffi_type.get_value_from_pointer(self)
23
+ # FIXME: This is a hack, since :c is not really a FFI type. Make
24
+ # SizedArray a type FFI understands instead.
25
+ when :c
26
+ self
23
27
  when Symbol
24
- adjust_value_out self.send("get_#{value_ffi_type}", 0)
28
+ self.send("get_#{value_ffi_type}", 0)
29
+ when FFI::Enum
30
+ value_ffi_type[self.get_int32(0)]
25
31
  else
26
32
  raise NotImplementedError
27
33
  end
28
34
  end
29
35
 
36
+ # Convert more fully to a ruby value than #to_value
37
+ def to_ruby_value
38
+ bare_value = to_value
39
+ case value_type
40
+ when :utf8
41
+ bare_value.to_utf8
42
+ when Array
43
+ value_type[1].wrap bare_value
44
+ when Class
45
+ value_type.wrap bare_value
46
+ else
47
+ bare_value
48
+ end
49
+ end
50
+
30
51
  def set_value value
31
- value = adjust_value_in value
32
52
  case value_ffi_type
33
53
  when Class
34
- self.put_bytes 0, value.to_ptr.read_bytes(value_type_size), 0, value_type_size
54
+ value_ffi_type.copy_value_to_pointer(value, self)
55
+ # FIXME: Make SizedArray an FFI DataConverter so it conflates with the code above.
56
+ when :c
57
+ GLib::SizedArray.copy_value_to_pointer(value, self)
35
58
  when Symbol
36
59
  self.send "put_#{value_ffi_type}", 0, value
60
+ when FFI::Enum
61
+ self.send "put_int32", 0, value_ffi_type.to_native(value, nil)
37
62
  else
38
- raise NotImplementedError
63
+ raise NotImplementedError, value_ffi_type
39
64
  end
40
65
  end
41
66
 
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
67
+ def clear
68
+ set_value nil_value
60
69
  end
61
70
 
62
71
  def self.for type
63
- self.new(type).tap {|ptr| ptr.set_value nil}
72
+ self.new(type).tap {|ptr| ptr.clear}
64
73
  end
65
74
 
66
75
  def self.from type, value
@@ -69,22 +78,12 @@ module GirFFI
69
78
 
70
79
  private
71
80
 
72
- def adjust_value_in value
73
- case @value_type
74
- when :gboolean
75
- value ? 1 : 0
76
- else
77
- value || nil_value
78
- end
81
+ def value_ffi_type
82
+ @value_ffi_type ||= TypeMap.type_specification_to_ffitype value_type
79
83
  end
80
84
 
81
- def adjust_value_out value
82
- case value_type
83
- when :gboolean
84
- value != 0
85
- else
86
- value
87
- end
85
+ def value_type_size
86
+ @value_type_size ||= FFI.type_size value_ffi_type
88
87
  end
89
88
 
90
89
  def nil_value
@@ -13,7 +13,11 @@ module GirFFI
13
13
  when Symbol
14
14
  from_basic_type_array type, ary
15
15
  when Class
16
- from_struct_array type, ary
16
+ if type == GObject::Value
17
+ from_gvalue_array type, ary
18
+ else
19
+ from_struct_array type, ary
20
+ end
17
21
  when Module
18
22
  from_enum_array type, ary
19
23
  when Array
@@ -33,20 +37,26 @@ module GirFFI
33
37
  when Module
34
38
  self.new type[val]
35
39
  when :void
36
- ArgHelper.object_to_inptr val
40
+ from_object val
37
41
  else
38
42
  raise NotImplementedError, type
39
43
  end
40
44
  end
41
45
 
42
46
  class << self
47
+ # FIXME: Hideous
48
+ def from_object obj
49
+ return nil if obj.nil?
50
+ return obj.to_ptr if obj.respond_to? :to_ptr
51
+
52
+ FFI::Pointer.new(obj.object_id).tap {|ptr|
53
+ ArgHelper::OBJECT_STORE[ptr.address] = obj }
54
+ end
43
55
 
44
56
  private
45
57
 
46
58
  def from_utf8_array ary
47
- ptr_ary = ary.map {|str| from_utf8 str}
48
- ptr_ary << nil
49
- from_basic_type_array :pointer, ptr_ary
59
+ from_basic_type_array :pointer, ary.map {|str| from_utf8 str}
50
60
  end
51
61
 
52
62
  def from_boolean_array ary
@@ -54,24 +64,28 @@ module GirFFI
54
64
  end
55
65
 
56
66
  def from_interface_pointer_array ary
57
- ptr_ary = ary.map {|ifc| ifc.to_ptr}
58
- ptr_ary << nil
59
- from_basic_type_array :pointer, ptr_ary
67
+ from_basic_type_array :pointer, ary.map {|ifc| ifc.to_ptr}
68
+ end
69
+
70
+ def from_gvalue_array type, ary
71
+ ary = ary.map do |it|
72
+ if it.is_a? GObject::Value
73
+ it
74
+ else
75
+ GObject::Value.wrap_ruby_value it
76
+ end
77
+ end
78
+ from_struct_array type, ary
60
79
  end
61
80
 
62
81
  def from_struct_array type, ary
63
82
  type_size = type::Struct.size
64
83
  length = ary.length
65
84
 
66
- # TODO: Find method to directly copy bytes, rather than reading and
67
- # putting them.
68
85
  ptr = AllocationHelper.safe_malloc length * type_size
69
- ary.each_with_index { |item, idx|
70
- ptr.put_bytes(idx * type_size,
71
- item.to_ptr.read_bytes(type_size),
72
- 0,
73
- type_size)
74
- }
86
+ ary.each_with_index do |item, idx|
87
+ type.copy_value_to_pointer item, ptr, idx * type_size
88
+ end
75
89
  new ptr
76
90
  end
77
91
 
@@ -88,11 +102,12 @@ module GirFFI
88
102
  def from_basic_type_array type, ary
89
103
  ffi_type = TypeMap.map_basic_type type
90
104
  length = ary.length
105
+ size = FFI.type_size ffi_type
91
106
 
92
- block = ArgHelper.allocate_array_of_type ffi_type, length + 1
107
+ block = AllocationHelper.safe_malloc size * (length + 1)
93
108
  block.send "put_array_of_#{ffi_type}", 0, ary
94
109
  block.send("put_#{ffi_type}",
95
- length * FFI.type_size(ffi_type),
110
+ length * size,
96
111
  (ffi_type == :pointer ? nil : 0))
97
112
 
98
113
  new block