gir_ffi 0.6.4 → 0.6.5

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 (40) hide show
  1. data/History.txt +6 -0
  2. data/lib/ffi-glib/array.rb +12 -3
  3. data/lib/ffi-glib/list_methods.rb +4 -0
  4. data/lib/ffi-glib/ptr_array.rb +4 -0
  5. data/lib/ffi-glib/sized_array.rb +4 -0
  6. data/lib/ffi-glib/strv.rb +4 -1
  7. data/lib/gir_ffi/arg_helper.rb +5 -27
  8. data/lib/gir_ffi/class_base.rb +8 -0
  9. data/lib/gir_ffi/enum_base.rb +8 -0
  10. data/lib/gir_ffi/ffi_ext/pointer.rb +12 -0
  11. data/lib/gir_ffi/in_out_pointer.rb +3 -13
  12. data/lib/gir_ffi/in_pointer.rb +19 -1
  13. data/lib/gir_ffi/info_ext/i_enum_info.rb +0 -2
  14. data/lib/gir_ffi/info_ext/i_object_info.rb +1 -1
  15. data/lib/gir_ffi/info_ext/i_type_info.rb +3 -14
  16. data/lib/gir_ffi/module_base.rb +1 -0
  17. data/lib/gir_ffi/type_map.rb +6 -8
  18. data/lib/gir_ffi/version.rb +1 -1
  19. data/lib/gir_ffi/zero_terminated.rb +5 -1
  20. data/tasks/test.rake +1 -0
  21. data/test/ffi-glib/array_test.rb +41 -7
  22. data/test/ffi-glib/hash_table_test.rb +3 -3
  23. data/test/ffi-glib/list_test.rb +31 -3
  24. data/test/ffi-glib/ptr_array_test.rb +28 -0
  25. data/test/ffi-glib/s_list_test.rb +28 -0
  26. data/test/ffi-glib/sized_array_test.rb +30 -3
  27. data/test/ffi-glib/strv_test.rb +31 -0
  28. data/test/ffi-gobject_test.rb +2 -2
  29. data/test/gir_ffi/arg_helper_test.rb +3 -2
  30. data/test/gir_ffi/class_base_test.rb +62 -4
  31. data/test/gir_ffi/function_builder_test.rb +1 -1
  32. data/test/gir_ffi/in_pointer_test.rb +17 -0
  33. data/test/gir_ffi/info_ext/i_object_info_test.rb +14 -0
  34. data/test/gir_ffi/info_ext/i_type_info_test.rb +79 -25
  35. data/test/gir_ffi/type_map_test.rb +15 -0
  36. data/test/gir_ffi/zero_terminated_test.rb +28 -0
  37. data/test/integration/generated_gimarshallingtests_test.rb +90 -75
  38. data/test/integration/generated_pango_test.rb +1 -1
  39. data/test/integration/generated_regress_test.rb +64 -39
  40. metadata +8 -18
@@ -1,3 +1,9 @@
1
+ == 0.6.5 / 2013-08-03
2
+
3
+ * Handle inline arrays of structs
4
+ * Implement equality operator for container types
5
+ * Fix element size calculation for GArray
6
+
1
7
  == 0.6.4 / 2013-06-30
2
8
 
3
9
  * Represent enum types by modules wrapping FFI::Enum
@@ -30,6 +30,7 @@ module GLib
30
30
  # Re-implementation of the g_array_index macro
31
31
  def index idx
32
32
  ptr = @struct[:data].get_pointer(idx * get_element_size)
33
+ # FIXME: Does not work for class-like values of element_type.
33
34
  GirFFI::ArgHelper.cast_from_pointer(element_type, ptr)
34
35
  end
35
36
 
@@ -43,6 +44,10 @@ module GLib
43
44
  Lib.g_array_get_element_size self
44
45
  end
45
46
 
47
+ def ==(other)
48
+ self.to_a == other.to_a
49
+ end
50
+
46
51
  def self.wrap elmttype, ptr
47
52
  super(ptr).tap do |array|
48
53
  array.element_type = elmttype if array
@@ -60,8 +65,12 @@ module GLib
60
65
  private
61
66
 
62
67
  def self.calculated_element_size type
63
- ffi_type = GirFFI::TypeMap.map_basic_type_or_string(type)
64
- FFI.type_size(ffi_type)
68
+ ffi_type = GirFFI::TypeMap.type_specification_to_ffitype(type)
69
+ if ffi_type.is_a? Symbol
70
+ FFI.type_size(ffi_type)
71
+ else
72
+ ffi_type.size
73
+ end
65
74
  end
66
75
 
67
76
  def calculated_element_size
@@ -70,7 +79,7 @@ module GLib
70
79
 
71
80
  def check_element_size_match
72
81
  unless calculated_element_size == self.get_element_size
73
- raise "Element sizes do not match"
82
+ warn "WARNING: Element sizes do not match"
74
83
  end
75
84
  end
76
85
  end
@@ -39,6 +39,10 @@ module GLib
39
39
  self
40
40
  end
41
41
 
42
+ def ==(other)
43
+ self.to_a == other.to_a
44
+ end
45
+
42
46
  private
43
47
 
44
48
  def reset_iterator
@@ -56,5 +56,9 @@ module GLib
56
56
  yield index(idx)
57
57
  end
58
58
  end
59
+
60
+ def ==(other)
61
+ self.to_a == other.to_a
62
+ end
59
63
  end
60
64
  end
@@ -25,6 +25,10 @@ module GLib
25
25
  end
26
26
  end
27
27
 
28
+ def ==(other)
29
+ self.to_a == other.to_a
30
+ end
31
+
28
32
  def self.wrap element_type, size, pointer
29
33
  new element_type, size, pointer unless pointer.null?
30
34
  end
@@ -1,6 +1,10 @@
1
1
  module GLib
2
2
  # Extra methods for GLib::Strv. The bulk is defined in `gir_ffi-base/glib/strv.rb`
3
3
  class Strv
4
+ def ==(other)
5
+ self.to_a == other.to_a
6
+ end
7
+
4
8
  def self.from it
5
9
  case it
6
10
  when nil
@@ -19,4 +23,3 @@ module GLib
19
23
  end
20
24
  end
21
25
  end
22
-
@@ -26,6 +26,8 @@ module GirFFI
26
26
  end
27
27
 
28
28
  def self.ptr_to_typed_array type, ptr, size
29
+ return [] if ptr.nil? or ptr.null?
30
+
29
31
  case type
30
32
  when Class
31
33
  ptr_to_interface_array type, ptr, size
@@ -33,37 +35,20 @@ module GirFFI
33
35
  ptr_to_enum_array type, ptr, size
34
36
  when Array
35
37
  ptr_to_interface_pointer_array type[1], ptr, size
36
- when FFI::Enum
37
- ptr_to_enum_array type, ptr, size
38
38
  when :utf8
39
39
  ptr_to_utf8_array ptr, size
40
40
  else
41
- self.send "ptr_to_#{type}_array", ptr, size
42
- end
43
- end
44
-
45
- def self.setup_ptr_to_type_array_handler_for *types
46
- types.flatten.each do |type|
47
41
  ffi_type = TypeMap.map_basic_type type
48
- defn =
49
- "def self.ptr_to_#{type}_array ptr, size
50
- return [] if ptr.nil? or ptr.null?
51
- ptr.get_array_of_#{ffi_type}(0, size)
52
- end"
53
- eval defn
42
+ ptr.send "get_array_of_#{ffi_type}", 0, size
54
43
  end
55
44
  end
56
45
 
57
- setup_ptr_to_type_array_handler_for SIMPLE_G_TYPES
58
-
59
46
  def self.ptr_to_utf8_array ptr, size
60
- return [] if ptr.nil? or ptr.null?
61
47
  ptrs = ptr.read_array_of_pointer(size)
62
48
  ptrs.map { |pt| ptr_to_utf8 pt }
63
49
  end
64
50
 
65
51
  def self.ptr_to_interface_array klass, ptr, size
66
- return [] if ptr.nil? or ptr.null?
67
52
  struct_size = klass::Struct.size
68
53
  size.times.map do |idx|
69
54
  klass.wrap(ptr + struct_size * idx)
@@ -71,7 +56,6 @@ module GirFFI
71
56
  end
72
57
 
73
58
  def self.ptr_to_interface_pointer_array klass, ptr, size
74
- return [] if ptr.nil? or ptr.null?
75
59
  ptrs = ptr.read_array_of_pointer(size)
76
60
  ptrs.map do |optr|
77
61
  klass.wrap(optr)
@@ -79,7 +63,7 @@ module GirFFI
79
63
  end
80
64
 
81
65
  def self.ptr_to_enum_array enum, ptr, size
82
- ptr_to_gint32_array(ptr, size).map {|val| enum[val] }
66
+ ptr.get_array_of_int32(0, size).map {|val| enum[val] }
83
67
  end
84
68
 
85
69
  if RUBY_VERSION < "1.9"
@@ -96,13 +80,6 @@ module GirFFI
96
80
  ptr.null? ? nil : ptr.read_string(len)
97
81
  end
98
82
 
99
- # Set up gtype handlers depending on type size.
100
- class << self
101
- sz = FFI.type_size(:size_t) * 8
102
- type = "guint#{sz}"
103
- alias_method :ptr_to_GType_array, "ptr_to_#{type}_array"
104
- end
105
-
106
83
  def self.check_error errpp
107
84
  err = GLib::Error.wrap(errpp.read_pointer)
108
85
  raise err.message if err
@@ -136,6 +113,7 @@ module GirFFI
136
113
  when :gint32
137
114
  cast_pointer_to_int32 it
138
115
  else
116
+ # FIXME: Only handles symbolic types.
139
117
  it.address
140
118
  end
141
119
  end
@@ -21,6 +21,10 @@ module GirFFI
21
21
  self.send method, *arguments, &block
22
22
  end
23
23
 
24
+ def ==(other)
25
+ other.is_a?(self.class) && self.to_ptr == other.to_ptr
26
+ end
27
+
24
28
  def self.setup_and_call method, *arguments, &block
25
29
  result = self.ancestors.any? do |klass|
26
30
  klass.respond_to?(:setup_method) &&
@@ -43,6 +47,10 @@ module GirFFI
43
47
  self.const_get :GIR_FFI_BUILDER
44
48
  end
45
49
 
50
+ def to_ffitype
51
+ self::Struct
52
+ end
53
+
46
54
  def setup_method name
47
55
  gir_ffi_builder.setup_method name
48
56
  end
@@ -4,6 +4,10 @@ module GirFFI
4
4
  self::Enum[arg]
5
5
  end
6
6
 
7
+ def to_native *args
8
+ self::Enum.to_native(*args)
9
+ end
10
+
7
11
  def setup_and_call method, *arguments, &block
8
12
  result = setup_method method.to_s
9
13
 
@@ -18,6 +22,10 @@ module GirFFI
18
22
  self.const_get :GIR_FFI_BUILDER
19
23
  end
20
24
 
25
+ def to_ffitype
26
+ self::Enum
27
+ end
28
+
21
29
  def setup_method name
22
30
  gir_ffi_builder.setup_method name
23
31
  end
@@ -13,6 +13,18 @@ module GirFFI
13
13
  # TODO: Move implementation here.
14
14
  ArgHelper.object_pointer_to_object self
15
15
  end
16
+
17
+ # XXX: int32 is size 4, bool is size 1. Why u no crash?
18
+ def put_bool offset, value
19
+ int = value ? 1 : 0
20
+ put_int32 offset, int
21
+ end
22
+
23
+ # XXX: int32 is size 4, bool is size 1. Why u no crash?
24
+ def get_bool offset
25
+ int = get_int32 offset
26
+ return (int != 0)
27
+ end
16
28
  end
17
29
  end
18
30
  end
@@ -5,7 +5,7 @@ module GirFFI
5
5
  attr_reader :value_type
6
6
 
7
7
  def initialize value, type
8
- @ffi_type = TypeMap.map_basic_type_or_string type
8
+ @ffi_type = TypeMap.type_specification_to_ffitype type
9
9
  @value_type = type
10
10
 
11
11
  value = adjust_value_in value
@@ -19,8 +19,7 @@ module GirFFI
19
19
  private :initialize
20
20
 
21
21
  def to_value
22
- value = self.send "get_#{@ffi_type}", 0
23
- adjust_value_out value
22
+ self.send "get_#{@ffi_type}", 0
24
23
  end
25
24
 
26
25
  def self.for type
@@ -39,7 +38,7 @@ module GirFFI
39
38
  def adjust_value_in value
40
39
  case @value_type
41
40
  when :gboolean
42
- (value ? 1 : 0)
41
+ value
43
42
  else
44
43
  value || nil_value
45
44
  end
@@ -48,14 +47,5 @@ module GirFFI
48
47
  def nil_value
49
48
  @ffi_type == :pointer ? nil : 0
50
49
  end
51
-
52
- def adjust_value_out value
53
- case @value_type
54
- when :gboolean
55
- (value != 0)
56
- else
57
- value
58
- end
59
- end
60
50
  end
61
51
  end
@@ -10,8 +10,10 @@ module GirFFI
10
10
  from_utf8_array ary
11
11
  when Symbol
12
12
  from_basic_type_array type, ary
13
+ when Class
14
+ from_struct_array type, ary
13
15
  when Module
14
- from_enum_array type::Enum, ary
16
+ from_enum_array type, ary
15
17
  when Array
16
18
  from_interface_pointer_array ary
17
19
  else
@@ -51,6 +53,22 @@ module GirFFI
51
53
  from_basic_type_array :pointer, ptr_ary
52
54
  end
53
55
 
56
+ def from_struct_array type, ary
57
+ type_size = type::Struct.size
58
+ length = ary.length
59
+
60
+ # TODO: Find method to directly copy bytes, rather than reading and
61
+ # putting them.
62
+ ptr = AllocationHelper.safe_malloc length * type_size
63
+ ary.each_with_index { |item, idx|
64
+ ptr.put_bytes(idx * type_size,
65
+ item.to_ptr.read_bytes(type_size),
66
+ 0,
67
+ type_size)
68
+ }
69
+ new ptr
70
+ end
71
+
54
72
  def from_enum_array type, ary
55
73
  from_basic_type_array :int32, ary.map {|sym| type.to_native sym, nil }
56
74
  end
@@ -2,7 +2,6 @@ module GirFFI
2
2
  module InfoExt
3
3
  module IEnumInfo
4
4
  def to_ffitype
5
- # TODO: It would make more sense if it were called Enum
6
5
  to_type::Enum
7
6
  end
8
7
  end
@@ -10,4 +9,3 @@ module GirFFI
10
9
  end
11
10
 
12
11
  GObjectIntrospection::IEnumInfo.send :include, GirFFI::InfoExt::IEnumInfo
13
-
@@ -2,7 +2,7 @@ module GirFFI
2
2
  module InfoExt
3
3
  module IObjectInfo
4
4
  def to_ffitype
5
- to_type::Struct
5
+ :pointer
6
6
  end
7
7
  end
8
8
  end
@@ -48,7 +48,7 @@ module GirFFI
48
48
  end
49
49
 
50
50
  def interface_type
51
- interface.info_type
51
+ tag == :interface && interface.info_type
52
52
  end
53
53
 
54
54
  def flattened_array_type
@@ -67,19 +67,8 @@ module GirFFI
67
67
  param_type(index).tag_or_class
68
68
  end
69
69
 
70
- # TODO: Merge with tag_or_class
71
70
  def tag_or_class_name
72
- type_tag = self.tag
73
- base = if type_tag == :interface
74
- interface_type_name
75
- else
76
- type_tag.inspect
77
- end
78
- if pointer? && type_tag != :utf8 && type_tag != :filename
79
- "[:pointer, #{base}]"
80
- else
81
- base
82
- end
71
+ tag_or_class.inspect
83
72
  end
84
73
 
85
74
  def tag_or_class
@@ -89,7 +78,7 @@ module GirFFI
89
78
  else
90
79
  type_tag
91
80
  end
92
- if pointer? && type_tag != :utf8 && type_tag != :filename
81
+ if pointer? && type_tag != :utf8 && type_tag != :filename || interface_type == :object
93
82
  [:pointer, base]
94
83
  else
95
84
  base
@@ -10,6 +10,7 @@ module GirFFI
10
10
  load_class(classname) || super
11
11
  end
12
12
 
13
+ # TODO: Rename to setup_class to match setup and setup_method.
13
14
  def load_class classname
14
15
  gir_ffi_builder.build_namespaced_class classname.to_s
15
16
  end
@@ -15,6 +15,7 @@ module GirFFI
15
15
  :struct => :pointer,
16
16
  :error => :pointer,
17
17
  :ptr_array => :pointer,
18
+ :array => :pointer,
18
19
  :utf8 => :pointer,
19
20
  :GType => gtype_type,
20
21
  :gboolean => :bool,
@@ -34,16 +35,13 @@ module GirFFI
34
35
  }
35
36
 
36
37
  def self.map_basic_type type
37
- TAG_TYPE_MAP[type] || type
38
+ sym = type.to_sym
39
+ TAG_TYPE_MAP[sym] || sym
38
40
  end
39
41
 
40
- # FIXME: Make name more descriptive.
41
- def self.map_basic_type_or_string type
42
- case type
43
- when :gboolean
44
- :int32
45
- when :utf8, :array
46
- :pointer
42
+ def self.type_specification_to_ffitype type
43
+ if Module === type
44
+ type.to_ffitype
47
45
  else
48
46
  map_basic_type(type)
49
47
  end
@@ -1,3 +1,3 @@
1
1
  module GirFFI
2
- VERSION = "0.6.4"
2
+ VERSION = "0.6.5"
3
3
  end
@@ -34,6 +34,10 @@ module GirFFI
34
34
  end
35
35
  end
36
36
 
37
+ def ==(other)
38
+ self.to_a == other.to_a
39
+ end
40
+
37
41
  private
38
42
 
39
43
  def read_value offset
@@ -42,7 +46,7 @@ module GirFFI
42
46
  end
43
47
 
44
48
  def ffi_type
45
- @ffi_type ||= TypeMap.map_basic_type_or_string basic_element_type
49
+ @ffi_type ||= TypeMap.type_specification_to_ffitype basic_element_type
46
50
  end
47
51
 
48
52
  def complex_element_type?