gir_ffi 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/History.txt +6 -0
  2. data/lib/ffi-glib.rb +1 -0
  3. data/lib/ffi-glib/array.rb +49 -10
  4. data/lib/ffi-glib/hash_table.rb +19 -5
  5. data/lib/ffi-glib/list.rb +4 -1
  6. data/lib/ffi-glib/list_methods.rb +8 -1
  7. data/lib/ffi-glib/s_list.rb +4 -1
  8. data/lib/ffi-glib/strv.rb +31 -0
  9. data/lib/ffi-gobject.rb +2 -35
  10. data/lib/ffi-gobject/base.rb +38 -0
  11. data/lib/ffi-gobject/object.rb +28 -30
  12. data/lib/ffi-gobject/value.rb +72 -56
  13. data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -1
  14. data/lib/ffi-gobject_introspection/lib.rb +3 -1
  15. data/lib/gir_ffi/arg_helper.rb +2 -19
  16. data/lib/gir_ffi/builder/argument.rb +239 -305
  17. data/lib/gir_ffi/builder/argument/base.rb +12 -9
  18. data/lib/gir_ffi/builder/argument/in_base.rb +2 -6
  19. data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
  20. data/lib/gir_ffi/builder/argument/out_base.rb +0 -11
  21. data/lib/gir_ffi/builder/field.rb +55 -0
  22. data/lib/gir_ffi/builder/function.rb +7 -7
  23. data/lib/gir_ffi/builder/module.rb +5 -7
  24. data/lib/gir_ffi/builder/type/object.rb +0 -33
  25. data/lib/gir_ffi/builder/type/registered_type.rb +0 -16
  26. data/lib/gir_ffi/builder/type/struct_based.rb +3 -3
  27. data/lib/gir_ffi/builder/type/unintrospectable.rb +1 -1
  28. data/lib/gir_ffi/builder/type/with_layout.rb +26 -58
  29. data/lib/gir_ffi/builder/type/with_methods.rb +9 -11
  30. data/lib/gir_ffi/class_base.rb +24 -6
  31. data/lib/gir_ffi/ffi_ext/pointer.rb +15 -0
  32. data/lib/gir_ffi/in_pointer.rb +10 -5
  33. data/lib/gir_ffi/info_ext/i_field_info.rb +15 -0
  34. data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
  35. data/lib/gir_ffi/method_stubber.rb +18 -0
  36. data/lib/gir_ffi/type_map.rb +1 -0
  37. data/lib/gir_ffi/variable_name_generator.rb +2 -0
  38. data/lib/gir_ffi/version.rb +1 -1
  39. data/test/builder_test.rb +6 -5
  40. data/test/ffi-glib/array_test.rb +40 -5
  41. data/test/ffi-glib/hash_table_test.rb +27 -3
  42. data/test/ffi-glib/list_test.rb +23 -0
  43. data/test/ffi-glib/strv_test.rb +41 -0
  44. data/test/ffi-gobject/gobject_test.rb +26 -22
  45. data/test/ffi-gobject/value_test.rb +26 -1
  46. data/test/ffi-gobject_introspection/lib_test.rb +10 -0
  47. data/test/gir_ffi_test_helper.rb +1 -1
  48. data/test/integration/derived_classes_test.rb +31 -0
  49. data/test/integration/generated_gimarshallingtests_test.rb +29 -15
  50. data/test/integration/generated_gio_test.rb +5 -6
  51. data/test/integration/generated_regress_test.rb +11 -7
  52. data/test/integration/method_lookup_test.rb +32 -0
  53. data/test/interface_type_builder_test.rb +1 -1
  54. data/test/test_helper.rb +38 -0
  55. data/test/unit/argument_builder_test.rb +16 -4
  56. data/test/unit/class_base_test.rb +48 -0
  57. data/test/unit/function_builder_test.rb +144 -4
  58. data/test/unit/hash_table_element_type_provider_test.rb +16 -0
  59. data/test/unit/i_field_info_test.rb +39 -0
  60. data/test/unit/i_type_info_test.rb +23 -0
  61. data/test/unit/list_element_type_provider_test.rb +13 -0
  62. data/test/unit/module_builder_test.rb +1 -1
  63. data/test/unit/object_type_builder_test.rb +0 -17
  64. data/test/unit/struct_builder_test.rb +27 -39
  65. metadata +118 -60
  66. data/lib/gir_ffi/builder/argument/hash_table_base.rb +0 -20
  67. data/lib/gir_ffi/builder/argument/list_base.rb +0 -16
  68. data/test/class_base_test.rb +0 -10
  69. data/test/function_definition_builder_test.rb +0 -130
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.2.3 / 2011-12-31
2
+
3
+ * Fix issue #7: methods that take GValues will autoconvert other values.
4
+ * Fix method lookup when include'ing a module that is an Interface.
5
+ * Various refactorings.
6
+
1
7
  == 0.2.2 / 2011-12-07
2
8
 
3
9
  * Fix issue #19: Check if a GLib::PtrArray.add method was generated
data/lib/ffi-glib.rb CHANGED
@@ -6,6 +6,7 @@ require 'ffi-glib/hash_table'
6
6
  require 'ffi-glib/byte_array'
7
7
  require 'ffi-glib/array'
8
8
  require 'ffi-glib/ptr_array'
9
+ require 'ffi-glib/strv'
9
10
 
10
11
  module GLib
11
12
  load_class :HFunc
@@ -6,14 +6,17 @@ module GLib
6
6
  class Array
7
7
  include Enumerable
8
8
 
9
- attr_accessor :element_type
9
+ attr_reader :element_type
10
+ def element_type= val
11
+ @element_type = val
12
+ check_element_size_match
13
+ end
10
14
 
11
15
  class << self
12
16
  undef :new
13
17
  def new type
14
- ffi_type = GirFFI::TypeMap.map_basic_type_or_string(type)
15
- wrap(Lib.g_array_new(0, 0, FFI.type_size(ffi_type))).tap {|it|
16
- it.element_type = type}
18
+ ptr = Lib.g_array_new(0, 0, calculated_element_size(type))
19
+ wrap type, ptr
17
20
  end
18
21
  end
19
22
 
@@ -24,16 +27,52 @@ module GLib
24
27
  self
25
28
  end
26
29
 
27
- # FIXME: Make GirFII::InPointer support #each and use that.
28
- def each &block
29
- to_typed_array.each(&block)
30
+ # Re-implementation of the g_array_index macro
31
+ def index idx
32
+ ptr = @struct[:data].get_pointer(idx * get_element_size)
33
+ GirFFI::ArgHelper.cast_from_pointer(element_type, ptr)
34
+ end
35
+
36
+ def each
37
+ @struct[:len].times.each do |idx|
38
+ yield index(idx)
39
+ end
40
+ end
41
+
42
+ def get_element_size
43
+ self.class.get_element_size self
44
+ end
45
+
46
+ def self.wrap elmttype, ptr
47
+ super(ptr).tap do |it|
48
+ break if it.nil?
49
+ it.element_type = elmttype
50
+ end
51
+ end
52
+
53
+ def self.from elmtype, it
54
+ case it
55
+ when self then it
56
+ when FFI::Pointer then wrap elmtype, it
57
+ else self.new(elmtype).tap {|arr| arr.append_vals it }
58
+ end
30
59
  end
31
60
 
32
61
  private
33
62
 
34
- def to_typed_array
35
- GirFFI::ArgHelper.ptr_to_typed_array(self.element_type,
36
- @struct[:data], @struct[:len])
63
+ def self.calculated_element_size type
64
+ ffi_type = GirFFI::TypeMap.map_basic_type_or_string(type)
65
+ FFI.type_size(ffi_type)
66
+ end
67
+
68
+ def calculated_element_size
69
+ self.class.calculated_element_size self.element_type
70
+ end
71
+
72
+ def check_element_size_match
73
+ unless calculated_element_size == self.get_element_size
74
+ raise "Element sizes do not match"
75
+ end
37
76
  end
38
77
  end
39
78
  end
@@ -37,26 +37,40 @@ module GLib
37
37
  else
38
38
  [nil, nil]
39
39
  end
40
- wrap(keytype, valtype, Lib.g_hash_table_new(hash_fn, eq_fn))
40
+ wrap [keytype, valtype], Lib.g_hash_table_new(hash_fn, eq_fn)
41
41
  end
42
42
 
43
- def wrap keytype, valtype, ptr
43
+ def wrap types, ptr
44
44
  super(ptr).tap do |it|
45
- break if it.nil?
45
+ return nil if it.nil?
46
+ keytype, valtype = *types
46
47
  it.key_type = keytype
47
48
  it.value_type = valtype
48
49
  end
49
50
  end
50
51
 
51
- def from_hash keytype, valtype, hash
52
+ def from_hash types, hash
53
+ keytype, valtype = *types
52
54
  return nil if hash.nil?
53
- return hash if hash.is_a? self
55
+ if hash.is_a? self
56
+ hash.key_type = keytype
57
+ hash.value_type = valtype
58
+ return hash
59
+ end
54
60
  ghash = self.new keytype, valtype
55
61
  hash.each do |key, val|
56
62
  ghash.insert key, val
57
63
  end
58
64
  ghash
59
65
  end
66
+
67
+ def from types, it
68
+ if it.is_a? FFI::Pointer
69
+ wrap types, it
70
+ else
71
+ from_hash types, it
72
+ end
73
+ end
60
74
  end
61
75
  end
62
76
  end
data/lib/ffi-glib/list.rb CHANGED
@@ -23,7 +23,10 @@ module GLib
23
23
 
24
24
  def from_array type, arr
25
25
  return nil if arr.nil?
26
- return arr if arr.is_a? self
26
+ if arr.is_a? self
27
+ arr.element_type = type
28
+ return arr
29
+ end
27
30
  arr.inject(self.new type) { |lst, val|
28
31
  lst.append val }
29
32
  end
@@ -32,8 +32,15 @@ module GLib
32
32
  it.element_type = elmttype
33
33
  end
34
34
  end
35
+
36
+ def from elmttype, it
37
+ if it.is_a? FFI::Pointer
38
+ wrap elmttype, it
39
+ else
40
+ from_array elmttype, it
41
+ end
42
+ end
35
43
  end
36
44
  end
37
45
  end
38
46
 
39
-
@@ -23,7 +23,10 @@ module GLib
23
23
 
24
24
  def from_array type, arr
25
25
  return nil if arr.nil?
26
- return arr if arr.is_a? self
26
+ if arr.is_a? self
27
+ arr.element_type = type
28
+ return arr
29
+ end
27
30
  arr.reverse.inject(self.new type) { |lst, val|
28
31
  lst.prepend val }
29
32
  end
@@ -0,0 +1,31 @@
1
+ module GLib
2
+ # Represents a null-terminated array of strings.
3
+ class Strv
4
+ include Enumerable
5
+
6
+ POINTER_SIZE = FFI.type_size(:pointer)
7
+
8
+ def initialize ptr
9
+ @ptr = ptr
10
+ end
11
+
12
+ def to_ptr
13
+ @ptr
14
+ end
15
+
16
+ def each
17
+ return if @ptr.null?
18
+ offset = 0
19
+ loop do
20
+ ptr = @ptr.get_pointer offset
21
+ break if ptr.null?
22
+ yield ptr.read_string
23
+ offset += POINTER_SIZE
24
+ end
25
+ end
26
+
27
+ def self.wrap ptr
28
+ self.new ptr
29
+ end
30
+ end
31
+ end
data/lib/ffi-gobject.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  GirFFI.setup :GObject
2
2
 
3
+ require 'ffi-gobject/base'
4
+
3
5
  require 'ffi-gobject/value'
4
6
  require 'ffi-gobject/initially_unowned'
5
7
  require 'ffi-gobject/closure'
@@ -83,39 +85,4 @@ module GObject
83
85
  [:pointer, ClosureMarshal], :void
84
86
  end
85
87
 
86
- TYPE_INVALID = type_from_name("invalid")
87
- TYPE_NONE = type_from_name("void")
88
- TYPE_INTERFACE = type_from_name("GInterface")
89
- TYPE_CHAR = type_from_name("gchar")
90
- TYPE_UCHAR = type_from_name("guchar")
91
- TYPE_BOOLEAN = type_from_name("gboolean")
92
- TYPE_INT = type_from_name("gint")
93
- TYPE_UINT = type_from_name("guint")
94
- TYPE_LONG = type_from_name("glong")
95
- TYPE_ULONG = type_from_name("gulong")
96
- TYPE_INT64 = type_from_name("gint64")
97
- TYPE_UINT64 = type_from_name("guint64")
98
- TYPE_ENUM = type_from_name("GEnum")
99
- TYPE_FLAGS = type_from_name("GFlags")
100
- TYPE_FLOAT = type_from_name("gfloat")
101
- TYPE_DOUBLE = type_from_name("gdouble")
102
- TYPE_STRING = type_from_name("gchararray")
103
- TYPE_POINTER = type_from_name("gpointer")
104
- TYPE_BOXED = type_from_name("GBoxed")
105
- TYPE_PARAM = type_from_name("GParam")
106
- TYPE_OBJECT = type_from_name("GObject")
107
- TYPE_GTYPE = type_from_name("GType")
108
- TYPE_VARIANT = type_from_name("GVariant")
109
- TYPE_HASH_TABLE = type_from_name("GHashTable")
110
-
111
- TYPE_TAG_TO_GTYPE = {
112
- :void => TYPE_NONE,
113
- :gboolean => TYPE_BOOLEAN,
114
- :gint32 => TYPE_INT,
115
- :gfloat => TYPE_FLOAT,
116
- :gdouble => TYPE_DOUBLE,
117
- :utf8 => TYPE_STRING,
118
- :ghash => TYPE_HASH_TABLE,
119
- :glist => TYPE_POINTER
120
- }
121
88
  end
@@ -0,0 +1,38 @@
1
+ module GObject
2
+ TYPE_INVALID = type_from_name("invalid")
3
+ TYPE_NONE = type_from_name("void")
4
+ TYPE_INTERFACE = type_from_name("GInterface")
5
+ TYPE_CHAR = type_from_name("gchar")
6
+ TYPE_UCHAR = type_from_name("guchar")
7
+ TYPE_BOOLEAN = type_from_name("gboolean")
8
+ TYPE_INT = type_from_name("gint")
9
+ TYPE_UINT = type_from_name("guint")
10
+ TYPE_LONG = type_from_name("glong")
11
+ TYPE_ULONG = type_from_name("gulong")
12
+ TYPE_INT64 = type_from_name("gint64")
13
+ TYPE_UINT64 = type_from_name("guint64")
14
+ TYPE_ENUM = type_from_name("GEnum")
15
+ TYPE_FLAGS = type_from_name("GFlags")
16
+ TYPE_FLOAT = type_from_name("gfloat")
17
+ TYPE_DOUBLE = type_from_name("gdouble")
18
+ TYPE_STRING = type_from_name("gchararray")
19
+ TYPE_POINTER = type_from_name("gpointer")
20
+ TYPE_BOXED = type_from_name("GBoxed")
21
+ TYPE_PARAM = type_from_name("GParam")
22
+ TYPE_OBJECT = type_from_name("GObject")
23
+ TYPE_GTYPE = type_from_name("GType")
24
+ TYPE_VARIANT = type_from_name("GVariant")
25
+ TYPE_STRV = GLib.strv_get_type
26
+ TYPE_HASH_TABLE = type_from_name("GHashTable")
27
+
28
+ TYPE_TAG_TO_GTYPE = {
29
+ :void => TYPE_NONE,
30
+ :gboolean => TYPE_BOOLEAN,
31
+ :gint32 => TYPE_INT,
32
+ :gfloat => TYPE_FLOAT,
33
+ :gdouble => TYPE_DOUBLE,
34
+ :utf8 => TYPE_STRING,
35
+ :ghash => TYPE_HASH_TABLE,
36
+ :glist => TYPE_POINTER
37
+ }
38
+ end
@@ -7,41 +7,21 @@ module GObject
7
7
  _setup_instance_method "set_property"
8
8
 
9
9
  def get_property_with_override property_name
10
- prop = self.class._find_property property_name
11
- type = prop.property_type
12
- v = Helper.gvalue_for_type_info type
13
- get_property_without_override property_name, v
10
+ type = get_property_type property_name
11
+ gvalue = Helper.gvalue_for_type_info type
14
12
 
15
- val = v.ruby_value
16
- case type.tag
17
- when :ghash
18
- GLib::HashTable.wrap type.param_type(0).tag, type.param_type(1).tag,
19
- val.to_ptr
20
- when :glist
21
- GLib::List.wrap type.param_type(0).tag, val
22
- else
23
- val
24
- end
13
+ get_property_without_override property_name, gvalue
14
+
15
+ adjust_value_to_type gvalue.ruby_value, type
25
16
  end
26
17
 
27
18
  def set_property_with_override property_name, value
28
- prop = self.class._find_property property_name
29
- type = prop.property_type
30
- v = Helper.gvalue_for_type_info type
19
+ type = get_property_type property_name
20
+ gvalue = Helper.gvalue_for_type_info type
31
21
 
32
- case type.tag
33
- when :glist
34
- lst = GLib::List.from_array type.param_type(0).tag, value
35
- v.set_value lst.to_ptr
36
- when :ghash
37
- hsh = GLib::HashTable.from_hash type.param_type(0).tag,
38
- type.param_type(1).tag, value
39
- v.set_value hsh.to_ptr
40
- else
41
- v.set_value value
42
- end
22
+ gvalue.set_value adjust_value_to_type(value, type)
43
23
 
44
- set_property_without_override property_name, v
24
+ set_property_without_override property_name, gvalue
45
25
  end
46
26
 
47
27
  alias get_property_without_override get_property
@@ -49,6 +29,24 @@ module GObject
49
29
 
50
30
  alias set_property_without_override set_property
51
31
  alias set_property set_property_with_override
32
+
33
+ private
34
+
35
+ def get_property_type property_name
36
+ prop = self.class._find_property property_name
37
+ prop.property_type
38
+ end
39
+
40
+ def adjust_value_to_type val, type
41
+ case type.tag
42
+ when :ghash
43
+ GLib::HashTable.from [type.param_type(0).tag, type.param_type(1).tag],
44
+ val
45
+ when :glist
46
+ GLib::List.from type.param_type(0).tag, val
47
+ else
48
+ val
49
+ end
50
+ end
52
51
  end
53
52
  end
54
-
@@ -11,40 +11,39 @@ module GObject
11
11
  set_value val
12
12
  end
13
13
 
14
+ TYPE_TO_SET_METHOD_MAP = {
15
+ TYPE_BOOLEAN => :set_boolean,
16
+ TYPE_INT => :set_int,
17
+ TYPE_STRING => :set_string,
18
+ TYPE_FLOAT => :set_float,
19
+ TYPE_DOUBLE => :set_double,
20
+ TYPE_OBJECT => :set_instance,
21
+ TYPE_BOXED => :set_boxed,
22
+ TYPE_POINTER => :set_pointer,
23
+ TYPE_ENUM => :set_enum
24
+ }
25
+
14
26
  def set_value val
15
- case current_fundamental_type
16
- when TYPE_BOOLEAN
17
- set_boolean val
18
- when TYPE_INT
19
- set_int val
20
- when TYPE_STRING
21
- set_string val
22
- when TYPE_FLOAT
23
- set_float val
24
- when TYPE_DOUBLE
25
- set_double val
26
- when TYPE_BOXED
27
- set_boxed val
28
- when TYPE_OBJECT
29
- set_instance val
30
- when TYPE_POINTER
31
- set_pointer val
32
- when TYPE_ENUM
33
- set_enum val
34
- else
35
- raise "Don't know how to handle #{current_gtype_name}"
36
- end
27
+ method = TYPE_TO_SET_METHOD_MAP[current_fundamental_type]
28
+ call_or_raise method, val
37
29
  self
38
30
  end
39
31
 
32
+ CLASS_TO_GTYPE_MAP = {
33
+ true => TYPE_BOOLEAN,
34
+ false => TYPE_BOOLEAN,
35
+ Integer => TYPE_INT,
36
+ String => TYPE_STRING
37
+ }
38
+
40
39
  def init_for_ruby_value val
41
- case val
42
- when true, false
43
- init TYPE_BOOLEAN
44
- when Integer
45
- init TYPE_INT
40
+ CLASS_TO_GTYPE_MAP.each do |klass, type|
41
+ if klass === val
42
+ init type
43
+ return self
44
+ end
46
45
  end
47
- self
46
+ raise "Can't handle #{val.class}"
48
47
  end
49
48
 
50
49
  def current_gtype
@@ -59,41 +58,58 @@ module GObject
59
58
  GObject.type_name current_gtype
60
59
  end
61
60
 
61
+ TYPE_TO_GET_METHOD_MAP = {
62
+ TYPE_BOOLEAN => :get_boolean,
63
+ TYPE_INT => :get_int,
64
+ TYPE_STRING => :get_string,
65
+ TYPE_FLOAT => :get_float,
66
+ TYPE_DOUBLE => :get_double,
67
+ TYPE_OBJECT => :get_object,
68
+ TYPE_BOXED => :get_boxed_enhanced,
69
+ TYPE_POINTER => :get_pointer
70
+ }
71
+
62
72
  def ruby_value
63
- case current_fundamental_type
64
- when TYPE_BOOLEAN
65
- get_boolean
66
- when TYPE_INT
67
- get_int
68
- when TYPE_STRING
69
- get_string
70
- when TYPE_FLOAT
71
- get_float
72
- when TYPE_DOUBLE
73
- get_double
74
- when TYPE_OBJECT
75
- get_object
76
- when TYPE_BOXED
77
- boxed = get_boxed
78
- case current_gtype_name.to_sym
79
- when :GStrv
80
- # FIXME: Extract this method to even lower level module.
81
- GirFFI::ArgHelper.strv_to_utf8_array boxed
82
- when :GHashTable
83
- GLib::HashTable.wrap :gpointer, :gpointer, boxed
73
+ method = TYPE_TO_GET_METHOD_MAP[current_fundamental_type]
74
+ call_or_raise method
75
+ end
76
+
77
+ class << self
78
+ def wrap_ruby_value val
79
+ self.new.set_ruby_value val
80
+ end
81
+
82
+ def from val
83
+ case val
84
+ when self
85
+ val
86
+ when nil
87
+ nil
84
88
  else
85
- GirFFI::ArgHelper.wrap_object_pointer_by_gtype boxed, current_gtype
89
+ wrap_ruby_value val
86
90
  end
87
- when TYPE_POINTER
88
- get_pointer
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def get_boxed_enhanced
97
+ boxed = get_boxed
98
+ case current_gtype
99
+ when TYPE_STRV
100
+ GLib::Strv.wrap boxed
101
+ when TYPE_HASH_TABLE
102
+ GLib::HashTable.wrap [:gpointer, :gpointer], boxed
89
103
  else
90
- raise "Don't know how to handle #{current_gtype_name}"
104
+ GirFFI::ArgHelper.wrap_object_pointer_by_gtype boxed, current_gtype
91
105
  end
92
106
  end
93
107
 
94
- class << self
95
- def wrap_ruby_value val
96
- self.new.set_ruby_value val
108
+ def call_or_raise method, *args
109
+ if method
110
+ send method, *args
111
+ else
112
+ raise "Don't know how to handle #{current_gtype_name}"
97
113
  end
98
114
  end
99
115
  end