gir_ffi 0.2.2 → 0.2.3

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 (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