gir_ffi 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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