gir_ffi 0.0.8 → 0.0.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 (46) hide show
  1. data/History.txt +11 -0
  2. data/TODO.rdoc +5 -0
  3. data/examples/01_empty_window.rb +0 -1
  4. data/examples/02_hello_world.rb +0 -1
  5. data/examples/03_upgraded_hello_world.rb +0 -1
  6. data/examples/04_webkit.rb +0 -1
  7. data/lib/gir_ffi/arg_helper.rb +231 -94
  8. data/lib/gir_ffi/builder/argument.rb +372 -46
  9. data/lib/gir_ffi/builder/module.rb +25 -10
  10. data/lib/gir_ffi/builder/type/constant.rb +39 -0
  11. data/lib/gir_ffi/builder/type/enum.rb +15 -5
  12. data/lib/gir_ffi/builder/type/registered_type.rb +25 -6
  13. data/lib/gir_ffi/builder/type/struct.rb +1 -9
  14. data/lib/gir_ffi/builder/type/union.rb +5 -0
  15. data/lib/gir_ffi/builder/type.rb +13 -14
  16. data/lib/gir_ffi/builder.rb +7 -4
  17. data/lib/gir_ffi/builder_helper.rb +4 -3
  18. data/lib/gir_ffi/i_base_info.rb +4 -0
  19. data/lib/gir_ffi/i_constant_info.rb +9 -0
  20. data/lib/gir_ffi/i_registered_type_info.rb +0 -1
  21. data/lib/gir_ffi/i_repository.rb +8 -2
  22. data/lib/gir_ffi/i_type_info.rb +7 -0
  23. data/lib/gir_ffi/lib.rb +41 -3
  24. data/lib/gir_ffi/overrides/glib.rb +188 -4
  25. data/lib/gir_ffi/overrides/gobject.rb +16 -5
  26. data/tasks/test.rake +1 -1
  27. data/test/arg_helper_test.rb +5 -5
  28. data/test/builder_test.rb +64 -41
  29. data/test/class_base_test.rb +1 -1
  30. data/test/function_definition_builder_test.rb +24 -2
  31. data/test/g_object_overrides_test.rb +1 -3
  32. data/test/g_object_test.rb +1 -1
  33. data/test/generated_gimarshallingtests_test.rb +1677 -0
  34. data/test/generated_gio_test.rb +1 -1
  35. data/test/generated_gtk_test.rb +31 -2
  36. data/test/generated_regress_test.rb +278 -54
  37. data/test/girffi_test.rb +20 -5
  38. data/test/glib_overrides_test.rb +81 -0
  39. data/test/gtk_overrides_test.rb +2 -3
  40. data/test/i_object_info_test.rb +1 -1
  41. data/test/i_repository_test.rb +3 -4
  42. data/test/lib/Makefile.am +18 -2
  43. data/test/module_builder_test.rb +1 -1
  44. data/test/test_helper.rb +88 -5
  45. data/test/type_builder_test.rb +7 -10
  46. metadata +16 -13
@@ -1,4 +1,4 @@
1
- require 'gir_ffi/builder/type/base'
1
+ require 'gir_ffi/builder/type/registered_type'
2
2
  module GirFFI
3
3
  module Builder
4
4
  module Type
@@ -6,7 +6,7 @@ module GirFFI
6
6
  # Implements the creation of an enum or flags type. The type will be
7
7
  # attached to the appropriate namespace module, and will be defined
8
8
  # as an enum for FFI.
9
- class Enum < Base
9
+ class Enum < RegisteredType
10
10
  def build_class
11
11
  unless defined? @klass
12
12
  instantiate_enum_class
@@ -14,10 +14,20 @@ module GirFFI
14
14
  @klass
15
15
  end
16
16
 
17
+ def value_spec
18
+ return info.values.map {|vinfo|
19
+ val = GirFFI::ArgHelper.cast_uint32_to_int32(vinfo.value)
20
+ [vinfo.name.to_sym, val]
21
+ }.flatten
22
+ end
23
+
17
24
  def instantiate_enum_class
18
- @klass = optionally_define_constant namespace_module, @classname do
19
- vals = info.values.map {|vinfo| [vinfo.name.to_sym, vinfo.value]}.flatten
20
- lib.enum(@classname.to_sym, vals)
25
+ if const_defined_for namespace_module, @classname
26
+ @klass = namespace_module.const_get @classname
27
+ else
28
+ @klass = namespace_module.const_set @classname,
29
+ lib.enum(@classname.to_sym, value_spec)
30
+ setup_gtype_getter
21
31
  end
22
32
  end
23
33
  end
@@ -1,4 +1,6 @@
1
1
  require 'gir_ffi/builder/type/base'
2
+ require 'gir_ffi/class_base'
3
+
2
4
  module GirFFI
3
5
  module Builder
4
6
  module Type
@@ -12,7 +14,14 @@ module GirFFI
12
14
  meta = (class << klass; self; end)
13
15
 
14
16
  go = method_introspection_data method
15
- raise NoMethodError unless go
17
+ if go.nil?
18
+ if parent
19
+ return superclass.gir_ffi_builder.setup_method method
20
+ else
21
+ raise NoMethodError
22
+ end
23
+ end
24
+
16
25
  attach_and_define_method method, go, meta
17
26
  end
18
27
 
@@ -88,6 +97,7 @@ module GirFFI
88
97
  end.flatten
89
98
  end
90
99
 
100
+ # FIXME: Move this into a class with the other type knowledge.
91
101
  def itypeinfo_to_ffitype_for_struct typeinfo
92
102
  ffitype = Builder.itypeinfo_to_ffitype typeinfo
93
103
  if ffitype.kind_of?(Class) and const_defined_for ffitype, :Struct
@@ -122,17 +132,26 @@ module GirFFI
122
132
  "
123
133
  end
124
134
 
135
+ # TODO: Rename the created method, or use a constant.
125
136
  def setup_gtype_getter
126
- getter = info.type_init
127
- return if getter.nil? or getter == "intern"
128
- lib.attach_function getter.to_sym, [], :size_t
129
- @klass.class_eval "
137
+ gtype = info.g_type
138
+ return if gtype.nil?
139
+ @klass.instance_eval "
130
140
  def self.get_gtype
131
- ::#{lib}.#{getter}
141
+ #{gtype}
132
142
  end
133
143
  "
134
144
  end
135
145
 
146
+ # FIXME: Only used in some of the subclases. Make mixin?
147
+ def provide_constructor
148
+ return if info.find_method 'new'
149
+
150
+ (class << @klass; self; end).class_eval {
151
+ alias_method :new, :allocate
152
+ }
153
+ end
154
+
136
155
  def parent
137
156
  nil
138
157
  end
@@ -7,15 +7,7 @@ module GirFFI
7
7
  class Struct < StructBased
8
8
  def setup_class
9
9
  super
10
- provide_struct_constructor
11
- end
12
-
13
- def provide_struct_constructor
14
- return if info.find_method 'new'
15
-
16
- (class << @klass; self; end).class_eval {
17
- alias_method :new, :allocate
18
- }
10
+ provide_constructor
19
11
  end
20
12
  end
21
13
  end
@@ -18,6 +18,11 @@ module GirFFI
18
18
  @structklass = get_or_define_class @klass, :Struct, FFI::Union
19
19
  setup_class unless already_set_up
20
20
  end
21
+
22
+ def setup_class
23
+ super
24
+ provide_constructor
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -1,6 +1,7 @@
1
1
  require 'gir_ffi/builder_helper'
2
2
  require 'gir_ffi/builder/type/base'
3
3
  require 'gir_ffi/builder/type/callback'
4
+ require 'gir_ffi/builder/type/constant'
4
5
  require 'gir_ffi/builder/type/enum'
5
6
  require 'gir_ffi/builder/type/union'
6
7
  require 'gir_ffi/builder/type/object'
@@ -12,21 +13,19 @@ module GirFFI
12
13
  # repository.
13
14
  module Builder
14
15
  module Type
16
+ TYPE_MAP = {
17
+ :callback => Callback,
18
+ :constant => Constant,
19
+ :enum => Enum,
20
+ :flags => Enum,
21
+ :interface => Interface,
22
+ :object => Object,
23
+ :struct => Struct,
24
+ :union => Union
25
+ }
26
+
15
27
  def self.build info
16
- case info.info_type
17
- when :callback
18
- Callback
19
- when :enum, :flags
20
- Enum
21
- when :union
22
- Union
23
- when :object
24
- Object
25
- when :struct
26
- Struct
27
- when :interface
28
- Interface
29
- end.new(info).build_class
28
+ TYPE_MAP[info.info_type].new(info).build_class
30
29
  end
31
30
  end
32
31
  end
@@ -1,6 +1,3 @@
1
- require 'gir_ffi/arg_helper'
2
- require 'gir_ffi/builder/function'
3
- require 'gir_ffi/class_base'
4
1
  require 'gir_ffi/builder/type'
5
2
  require 'gir_ffi/builder/module'
6
3
  require 'gir_ffi/builder_helper'
@@ -15,10 +12,12 @@ module GirFFI
15
12
  TAG_TYPE_MAP = {
16
13
  :GType => :size_t,
17
14
  :gboolean => :bool,
15
+ :gunichar => :uint32,
18
16
  :gint8 => :int8,
19
17
  :guint8 => :uint8,
20
18
  :gint16 => :int16,
21
19
  :guint16 => :uint16,
20
+ :gint => :int,
22
21
  :gint32 => :int32,
23
22
  :guint32 => :uint32,
24
23
  :gint64 => :int64,
@@ -36,6 +35,10 @@ module GirFFI
36
35
  Builder::Module.new(namespace, version).generate
37
36
  end
38
37
 
38
+ def self.build_module_non_recursive namespace, version=nil
39
+ Builder::Module.new(namespace, version).build_module_non_recursive
40
+ end
41
+
39
42
  def self.attach_ffi_function lib, info
40
43
  sym = info.symbol
41
44
  argtypes = ffi_function_argument_types info
@@ -68,7 +71,7 @@ module GirFFI
68
71
  if tag == :interface
69
72
  return build_class info.interface
70
73
  else
71
- return TAG_TYPE_MAP[tag]
74
+ return TAG_TYPE_MAP[tag] || tag
72
75
  end
73
76
  end
74
77
 
@@ -9,10 +9,11 @@ module GirFFI
9
9
  end
10
10
 
11
11
  def optionally_define_constant parent, name
12
- unless const_defined_for parent, name
13
- parent.const_set name, yield
12
+ if const_defined_for parent, name
13
+ parent.const_get name
14
+ else
15
+ parent.const_set name, yield
14
16
  end
15
- parent.const_get name
16
17
  end
17
18
 
18
19
  end
@@ -45,6 +45,10 @@ module GirFFI
45
45
  Lib.g_base_info_get_namespace @gobj
46
46
  end
47
47
 
48
+ def safe_namespace
49
+ namespace.gsub(/^(.)/) { $1.upcase }
50
+ end
51
+
48
52
  def container
49
53
  ptr = Lib.g_base_info_get_container @gobj
50
54
  IRepository.wrap_ibaseinfo_pointer ptr
@@ -2,5 +2,14 @@ module GirFFI
2
2
  # Wraps a GIConstantInfo struct; represents an constant.
3
3
  # Not implemented yet.
4
4
  class IConstantInfo < IBaseInfo
5
+ def value
6
+ val = Lib::GIArgument.new
7
+ size = Lib.g_constant_info_get_value @gobj, val
8
+ return val
9
+ end
10
+
11
+ def constant_type
12
+ ITypeInfo.wrap(Lib.g_constant_info_get_type @gobj)
13
+ end
5
14
  end
6
15
  end
@@ -1,7 +1,6 @@
1
1
  module GirFFI
2
2
  # Wraps a GIRegisteredTypeInfo struct.
3
3
  # Represents a registered type.
4
- # Not implemented yet.
5
4
  class IRegisteredTypeInfo < IBaseInfo
6
5
  def type_name
7
6
  Lib.g_registered_type_info_get_type_name @gobj
@@ -20,6 +20,7 @@ require 'gir_ffi/i_union_info'
20
20
  require 'gir_ffi/i_enum_info'
21
21
  require 'gir_ffi/i_flags_info'
22
22
  require 'gir_ffi/i_error_domain_info'
23
+ require 'gir_ffi/arg_helper'
23
24
 
24
25
  module GirFFI
25
26
  # The Gobject Introspection Repository. This class is the point of
@@ -72,10 +73,10 @@ module GirFFI
72
73
  Lib.g_type_tag_to_string type
73
74
  end
74
75
 
75
- def require namespace, version=nil
76
+ def require namespace, version=nil, flags=0
76
77
  errpp = FFI::MemoryPointer.new(:pointer).write_pointer nil
77
78
 
78
- Lib.g_irepository_require @gobj, namespace, version, 0, errpp
79
+ Lib.g_irepository_require @gobj, namespace, version, flags, errpp
79
80
 
80
81
  errp = errpp.read_pointer
81
82
  raise GError.new(errp)[:message] unless errp.null?
@@ -107,6 +108,11 @@ module GirFFI
107
108
  return wrap ptr
108
109
  end
109
110
 
111
+ def dependencies namespace
112
+ strv = Lib.g_irepository_get_dependencies @gobj, namespace
113
+ ArgHelper.strv_to_utf8_array strv
114
+ end
115
+
110
116
  def shared_library namespace
111
117
  Lib.g_irepository_get_shared_library @gobj, namespace
112
118
  end
@@ -15,12 +15,19 @@ module GirFFI
15
15
  ptr = Lib.g_type_info_get_interface @gobj
16
16
  IRepository.wrap_ibaseinfo_pointer ptr
17
17
  end
18
+
18
19
  def array_length
19
20
  Lib.g_type_info_get_array_length @gobj
20
21
  end
22
+
21
23
  def array_fixed_size
22
24
  Lib.g_type_info_get_array_fixed_size @gobj
23
25
  end
26
+
27
+ def array_type
28
+ Lib.g_type_info_get_array_type @gobj
29
+ end
30
+
24
31
  def zero_terminated?
25
32
  Lib.g_type_info_is_zero_terminated @gobj
26
33
  end
data/lib/gir_ffi/lib.rb CHANGED
@@ -18,8 +18,10 @@ module GirFFI
18
18
  [:pointer, :string, :int], :pointer
19
19
  attach_function :g_irepository_find_by_name,
20
20
  [:pointer, :string, :string], :pointer
21
- attach_function :g_irepository_find_by_gtype, [:pointer, :size_t], :pointer
22
-
21
+ attach_function :g_irepository_find_by_gtype,
22
+ [:pointer, :size_t], :pointer
23
+ attach_function :g_irepository_get_dependencies,
24
+ [:pointer, :string], :pointer
23
25
  attach_function :g_irepository_get_shared_library,
24
26
  [:pointer, :string], :string
25
27
 
@@ -112,12 +114,20 @@ module GirFFI
112
114
 
113
115
  #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY)
114
116
 
117
+ enum :IArrayType, [
118
+ :c,
119
+ :array,
120
+ :ptr_array,
121
+ :byte_array
122
+ ]
123
+
115
124
  attach_function :g_type_info_is_pointer, [:pointer], :bool
116
125
  attach_function :g_type_info_get_tag, [:pointer], :ITypeTag
117
126
  attach_function :g_type_info_get_param_type, [:pointer, :int], :pointer
118
127
  attach_function :g_type_info_get_interface, [:pointer], :pointer
119
128
  attach_function :g_type_info_get_array_length, [:pointer], :int
120
129
  attach_function :g_type_info_get_array_fixed_size, [:pointer], :int
130
+ attach_function :g_type_info_get_array_type, [:pointer], :IArrayType
121
131
  attach_function :g_type_info_is_zero_terminated, [:pointer], :bool
122
132
  attach_function :g_type_info_get_n_error_domains, [:pointer], :int
123
133
  attach_function :g_type_info_get_error_domain, [:pointer, :int], :pointer
@@ -216,6 +226,34 @@ module GirFFI
216
226
  attach_function :g_interface_info_get_n_constants, [:pointer], :int
217
227
  attach_function :g_interface_info_get_constant, [:pointer, :int], :pointer
218
228
  attach_function :g_interface_info_get_iface_struct, [:pointer], :pointer
219
-
229
+
230
+ class GIArgument < FFI::Union
231
+ layout :v_boolean, :int,
232
+ :v_int8, :int8,
233
+ :v_uint8, :uint8,
234
+ :v_int16, :int16,
235
+ :v_uint16, :uint16,
236
+ :v_int32, :int32,
237
+ :v_uint32, :uint32,
238
+ :v_int64, :int64,
239
+ :v_uint64, :uint64,
240
+ :v_float, :float,
241
+ :v_double, :double,
242
+ :v_short, :short,
243
+ :v_ushort, :ushort,
244
+ :v_int, :int,
245
+ :v_uint, :uint,
246
+ :v_long, :long,
247
+ :v_ulong, :ulong,
248
+ :v_ssize, :size_t, # FIXME: Needs to be signed.
249
+ :v_size, :size_t,
250
+ :v_string, :string,
251
+ :v_pointer, :pointer
252
+ end
253
+
254
+ # IConstInfo
255
+ #
256
+ attach_function :g_constant_info_get_type, [:pointer], :pointer
257
+ attach_function :g_constant_info_get_value, [:pointer, :pointer], :int
220
258
  end
221
259
  end
@@ -3,25 +3,209 @@ module GirFFI
3
3
  module GLib
4
4
  def self.included base
5
5
  base.extend ClassMethods
6
+ extend_classes(base)
6
7
  attach_non_introspectable_functions(base)
7
8
  end
8
9
 
10
+ def self.extend_classes base
11
+ base::SList.class_eval {
12
+ attr_accessor :element_type
13
+ include ListInstanceMethods
14
+ extend ListClassMethods
15
+ include Enumerable
16
+ }
17
+ base::List.class_eval {
18
+ attr_accessor :element_type
19
+ include ListInstanceMethods
20
+ extend ListClassMethods
21
+ include Enumerable
22
+ }
23
+ base::HashTable.class_eval {
24
+ attr_accessor :key_type
25
+ attr_accessor :value_type
26
+ include HashTableInstanceMethods
27
+ extend HashTableClassMethods
28
+ include Enumerable
29
+ }
30
+ base::ByteArray.class_eval {
31
+ include ByteArrayInstanceMethods
32
+ }
33
+ base::Array.class_eval {
34
+ attr_accessor :element_type
35
+ include ArrayInstanceMethods
36
+ }
37
+ end
38
+
9
39
  def self.attach_non_introspectable_functions base
10
40
  base::Lib.attach_function :g_slist_prepend, [:pointer, :pointer],
11
41
  :pointer
12
42
  base::Lib.attach_function :g_list_append, [:pointer, :pointer],
13
43
  :pointer
44
+ base::Lib.attach_function :g_hash_table_foreach,
45
+ [:pointer, base::HFunc, :pointer], :void
46
+ base::Lib.attach_function :g_hash_table_new,
47
+ [base::HashFunc, base::EqualFunc], :pointer
48
+ base::Lib.attach_function :g_hash_table_insert,
49
+ [:pointer, :pointer, :pointer], :void
50
+ base::Lib.attach_function :g_byte_array_new, [], :pointer
51
+ base::Lib.attach_function :g_byte_array_append,
52
+ [:pointer, :pointer, :uint], :pointer
53
+ base::Lib.attach_function :g_array_new, [:int, :int, :uint], :pointer
54
+ base::Lib.attach_function :g_array_append_vals,
55
+ [:pointer, :pointer, :uint], :pointer
14
56
  end
15
57
 
16
58
  module ClassMethods
17
- # FIXME: Should not be so visible for end users.
59
+ # FIXME: Turn into real constructor
60
+ def slist_new elmttype
61
+ ::GLib::List._real_new(FFI::Pointer.new(0)).tap {|it|
62
+ it.element_type = elmttype}
63
+ end
64
+
65
+ # FIXME: Turn into instance method; Use element type.
18
66
  def slist_prepend slist, data
19
- ::GLib::SList.wrap(::GLib::Lib.g_slist_prepend slist, data)
67
+ ::GLib::SList.wrap(slist.element_type, ::GLib::Lib.g_slist_prepend(slist, data))
68
+ end
69
+
70
+ # FIXME: Turn into real constructor
71
+ def list_new elmttype
72
+ ::GLib::List._real_new(FFI::Pointer.new(0)).tap {|it|
73
+ it.element_type = elmttype}
20
74
  end
21
75
 
22
- # FIXME: Should not be so visible for end users.
76
+ # FIXME: Turn into instance method; Use element type.
23
77
  def list_append list, data
24
- ::GLib::List.wrap(::GLib::Lib.g_list_append list, data)
78
+ ::GLib::List.wrap(list.element_type, ::GLib::Lib.g_list_append(list, data))
79
+ end
80
+
81
+ # FIXME: Turn into real constructor
82
+ def hash_table_new keytype, valtype
83
+ hash_fn, eq_fn = case keytype
84
+ when :utf8
85
+ lib = ::GLib::Lib.ffi_libraries.first
86
+ [ FFI::Function.new(:uint, [:pointer], lib.find_function("g_str_hash")),
87
+ FFI::Function.new(:int, [:pointer, :pointer], lib.find_function("g_str_equal"))]
88
+ else
89
+ [nil, nil]
90
+ end
91
+
92
+ ::GLib::HashTable.wrap(keytype, valtype, ::GLib::Lib.g_hash_table_new(hash_fn, eq_fn))
93
+ end
94
+
95
+ # FIXME: Turn into real constructor
96
+ def byte_array_new
97
+ ::GLib::ByteArray.wrap(::GLib::Lib.g_byte_array_new)
98
+ end
99
+
100
+ # FIXME: Turn into instance method
101
+ def byte_array_append arr, data
102
+ bytes = GirFFI::ArgHelper.utf8_to_inptr data
103
+ len = data.bytesize
104
+ ::GLib::ByteArray.wrap(::GLib::Lib.g_byte_array_append arr.to_ptr, bytes, len)
105
+ end
106
+
107
+ # FIXME: Turn into real constructor
108
+ def array_new type
109
+ ffi_type = type == :utf8 ? :pointer : type
110
+ arr = ::GLib::Array.wrap(
111
+ ::GLib::Lib.g_array_new(0, 0, FFI.type_size(ffi_type)))
112
+ arr.element_type = type
113
+ arr
114
+ end
115
+
116
+ # FIXME: Turn into instance method
117
+ def array_append_vals arr, data
118
+ bytes = GirFFI::ArgHelper.typed_array_to_inptr arr.element_type, data
119
+ len = data.length
120
+ res = ::GLib::Array.wrap(
121
+ ::GLib::Lib.g_array_append_vals(arr.to_ptr, bytes, len))
122
+ res.element_type = arr.element_type
123
+ res
124
+ end
125
+
126
+ end
127
+
128
+ module ListInstanceMethods
129
+ def each
130
+ list = self
131
+ rval = nil
132
+ until list.nil?
133
+ rval = yield GirFFI::ArgHelper.cast_from_pointer(element_type, list[:data])
134
+ list = self.class.wrap(element_type, list[:next])
135
+ end
136
+ rval
137
+ end
138
+ end
139
+
140
+ module ListClassMethods
141
+ def wrap elmttype, ptr
142
+ super(ptr).tap do |it|
143
+ break if it.nil?
144
+ it.element_type = elmttype
145
+ end
146
+ end
147
+ end
148
+
149
+ module HashTableClassMethods
150
+ def wrap keytype, valtype, ptr
151
+ super(ptr).tap do |it|
152
+ break if it.nil?
153
+ it.key_type = keytype
154
+ it.value_type = valtype
155
+ end
156
+ end
157
+ end
158
+
159
+ module HashTableInstanceMethods
160
+ def each
161
+ prc = Proc.new {|keyptr, valptr, userdata|
162
+ key = cast_from_pointer key_type, keyptr
163
+ val = cast_from_pointer value_type, valptr
164
+ yield key, val
165
+ }
166
+ ::GLib::Lib.g_hash_table_foreach self.to_ptr, prc, nil
167
+ end
168
+
169
+ def to_hash
170
+ Hash[self.to_a]
171
+ end
172
+
173
+ def insert key, value
174
+ keyptr = cast_to_pointer key_type, key
175
+ valptr = cast_to_pointer value_type, value
176
+ ::GLib::Lib.g_hash_table_insert self.to_ptr, keyptr, valptr
177
+ end
178
+
179
+ def cast_to_pointer type, it
180
+ if type == :utf8
181
+ GirFFI::ArgHelper.utf8_to_inptr it
182
+ else
183
+ FFI::Pointer.new(it)
184
+ end
185
+ end
186
+
187
+ def cast_from_pointer type, it
188
+ case type
189
+ when :utf8
190
+ GirFFI::ArgHelper.ptr_to_utf8 it
191
+ when :gint32
192
+ GirFFI::ArgHelper.cast_pointer_to_int32 it
193
+ else
194
+ it.address
195
+ end
196
+ end
197
+ end
198
+
199
+ module ByteArrayInstanceMethods
200
+ def to_string
201
+ GirFFI::ArgHelper.ptr_to_utf8_length self[:data], self[:len]
202
+ end
203
+ end
204
+
205
+ module ArrayInstanceMethods
206
+ def to_a
207
+ GirFFI::ArgHelper.ptr_to_typed_array(self.element_type,
208
+ self[:data], self[:len])
25
209
  end
26
210
  end
27
211
  end
@@ -30,6 +30,12 @@ module GirFFI
30
30
  end
31
31
 
32
32
  def self.build_extra_classes base
33
+ build_ruby_closure_class base
34
+ end
35
+
36
+ # Build the GObject::RubyClosure class. This class encapsulates Ruby
37
+ # blocks as GObject Closures.
38
+ def self.build_ruby_closure_class base
33
39
  klass = Class.new(base::Closure) do
34
40
  const_set :BLOCK_STORE, {}
35
41
 
@@ -41,8 +47,7 @@ module GirFFI
41
47
  def self.new &block
42
48
  raise ArgumentError unless block_given?
43
49
  wrap(new_simple(self::Struct.size, nil).to_ptr).tap do |it|
44
- # XXX: Check that this methods is fool-proof!
45
- h = block.hash
50
+ h = block.object_id
46
51
  self::BLOCK_STORE[h] = block
47
52
  it[:blockhash] = h
48
53
  it.set_marshal Proc.new {|*args| marshaller(*args)}
@@ -272,11 +277,17 @@ module GirFFI
272
277
  end
273
278
 
274
279
  def ruby_value
275
- case current_gtype_name
276
- when "gboolean"
280
+ case current_gtype_name.to_sym
281
+ when :gboolean
277
282
  get_boolean
278
- when "gint"
283
+ when :gint
279
284
  get_int
285
+ when :gchararray
286
+ get_string
287
+ when :GDate
288
+ ::GLib::Date.wrap(get_boxed)
289
+ when :GStrv
290
+ ArgHelper.strv_to_utf8_array get_boxed
280
291
  else
281
292
  nil
282
293
  end
data/tasks/test.rake CHANGED
@@ -17,7 +17,7 @@ namespace :test do
17
17
  end
18
18
 
19
19
  file "test/lib/Makefile" => "test/lib/configure" do
20
- sh %{cd test/lib && ./configure}
20
+ sh %{cd test/lib && ./configure --enable-maintainer-mode}
21
21
  end
22
22
 
23
23
  file "test/lib/configure" do
@@ -1,9 +1,9 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
2
 
3
- class ArgHelperTest < Test::Unit::TestCase
4
- context "The int_to_inoutptr method's return value" do
3
+ class ArgHelperTest < MiniTest::Spec
4
+ context "The gint32_to_inoutptr method's return value" do
5
5
  setup do
6
- @result = GirFFI::ArgHelper.int_to_inoutptr 24
6
+ @result = GirFFI::ArgHelper.gint32_to_inoutptr 24
7
7
  end
8
8
 
9
9
  should "be an FFI::Pointer" do
@@ -38,14 +38,14 @@ class ArgHelperTest < Test::Unit::TestCase
38
38
  end
39
39
  end
40
40
 
41
- context "The outptr_to_int method" do
41
+ context "The outptr_to_gint32 method" do
42
42
  setup do
43
43
  @ptr = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:int)
44
44
  @ptr.write_int 342
45
45
  end
46
46
 
47
47
  should "retrieve the correct integer value" do
48
- assert_equal 342, GirFFI::ArgHelper.outptr_to_int(@ptr)
48
+ assert_equal 342, GirFFI::ArgHelper.outptr_to_gint32(@ptr)
49
49
  end
50
50
  end
51
51