gir_ffi 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +10 -0
- data/Rakefile +9 -1
- data/TODO.md +4 -0
- data/lib/ffi-glib.rb +5 -0
- data/lib/ffi-glib/bytes.rb +49 -0
- data/lib/ffi-glib/container_class_methods.rb +1 -4
- data/lib/ffi-glib/error.rb +17 -0
- data/lib/ffi-gobject/value.rb +6 -3
- data/lib/ffi-gobject_introspection/i_callback_info.rb +0 -1
- data/lib/ffi-gobject_introspection/i_constant_info.rb +10 -10
- data/lib/ffi-gobject_introspection/i_repository.rb +20 -20
- data/lib/ffi-gobject_introspection/i_vfunc_info.rb +7 -0
- data/lib/ffi-gobject_introspection/lib.rb +1 -7
- data/lib/gir_ffi/arg_helper.rb +23 -2
- data/lib/gir_ffi/builders/argument_builder.rb +15 -1
- data/lib/gir_ffi/builders/base_argument_builder.rb +1 -0
- data/lib/gir_ffi/builders/callback_argument_builder.rb +49 -7
- data/lib/gir_ffi/builders/callback_return_value_builder.rb +6 -2
- data/lib/gir_ffi/builders/closure_convertor.rb +1 -1
- data/lib/gir_ffi/builders/null_convertor.rb +1 -0
- data/lib/gir_ffi/builders/property_builder.rb +1 -1
- data/lib/gir_ffi/builders/return_value_builder.rb +1 -1
- data/lib/gir_ffi/builders/type_builder.rb +9 -9
- data/lib/gir_ffi/builders/vfunc_builder.rb +3 -1
- data/lib/gir_ffi/callback_base.rb +6 -0
- data/lib/gir_ffi/error_argument_info.rb +12 -3
- data/lib/gir_ffi/error_type_info.rb +21 -0
- data/lib/gir_ffi/ffi_ext/pointer.rb +5 -6
- data/lib/gir_ffi/glib_error.rb +18 -0
- data/lib/gir_ffi/in_pointer.rb +1 -1
- data/lib/gir_ffi/info_ext/i_type_info.rb +44 -30
- data/lib/gir_ffi/info_ext/i_vfunc_info.rb +13 -1
- data/lib/gir_ffi/type_map.rb +30 -29
- data/lib/gir_ffi/user_defined_type_info.rb +1 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/lib/gir_ffi/vfunc_base.rb +1 -0
- data/lib/gir_ffi/zero_terminated.rb +3 -8
- data/test/base_test_helper.rb +1 -0
- data/test/ffi-glib/array_test.rb +2 -2
- data/test/ffi-glib/bytes_test.rb +54 -0
- data/test/ffi-glib/ptr_array_test.rb +2 -2
- data/test/ffi-gobject/value_test.rb +4 -4
- data/test/ffi-gobject_introspection/i_repository_test.rb +1 -1
- data/test/gir_ffi/builders/callback_argument_builder_test.rb +44 -0
- data/test/gir_ffi/builders/callback_builder_test.rb +1 -1
- data/test/gir_ffi/builders/callback_return_value_builder_test.rb +74 -0
- data/test/gir_ffi/builders/function_builder_test.rb +23 -2
- data/test/gir_ffi/builders/property_builder_test.rb +15 -0
- data/test/gir_ffi/builders/return_value_builder_test.rb +26 -26
- data/test/gir_ffi/builders/signal_builder_test.rb +5 -5
- data/test/gir_ffi/builders/union_builder_test.rb +2 -1
- data/test/gir_ffi/builders/vfunc_builder_test.rb +125 -4
- data/test/gir_ffi/error_type_info_test.rb +48 -0
- data/test/gir_ffi/in_pointer_test.rb +1 -1
- data/test/gir_ffi/sized_array_test.rb +2 -2
- data/test/integration/generated_gimarshallingtests_test.rb +199 -31
- data/test/integration/generated_regress_test.rb +37 -33
- metadata +214 -202
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1adc3c9b00a49fef5e4ae2dc6674c79c62dc56b6
|
4
|
+
data.tar.gz: 47303f482166c93c612ed7debdf2d2ed95aad752
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6983eb6497add24e59e8d8041b815fccd9615e8e9d42895a8e1afbacb44c180a9e6bf63a9a719c6c5bca0552c9fb426391aefe5f668ba44669a3e425554fc2f
|
7
|
+
data.tar.gz: b904270d51f8905733777fb1ad5e9f6c8da61dd44153c078c472befcd0eee83988ebc08d95d9bb0dc3f57866cd4b4638e45046239fac63a0aa5ddc7e23ba6f49
|
data/Changelog.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.7.4 / 2014-05-03
|
4
|
+
|
5
|
+
* Correctly handle closure data arguments originating from C
|
6
|
+
* Handle callee-allocated simple types for callbacks and functions
|
7
|
+
* Handle callback out parameters that are zero-terminated arrays
|
8
|
+
* Handle virtual functions with GError arguments
|
9
|
+
* Support the GBytes type
|
10
|
+
* Handle virtual functions returning GObjects
|
11
|
+
* Avoid overwriting methods with getters for properties with dashes in the name
|
12
|
+
|
3
13
|
## 0.7.3 / 2014-03-23
|
4
14
|
|
5
15
|
* Restore proper handling of enums in callback arguments
|
data/Rakefile
CHANGED
data/TODO.md
CHANGED
@@ -85,6 +85,10 @@ retrieve values from them by hand as well. Ideally, we would have `.from_ruby` a
|
|
85
85
|
require a specifice VariantType to be used consistently. Special logic will have
|
86
86
|
to be put in place for that.
|
87
87
|
|
88
|
+
## Handle ownership-transfer correctly
|
89
|
+
|
90
|
+
For how to handle objects, see https://bugzilla.gnome.org/show_bug.cgi?id=657202#c1
|
91
|
+
|
88
92
|
## See Also
|
89
93
|
|
90
94
|
dnote
|
data/lib/ffi-glib.rb
CHANGED
@@ -5,6 +5,8 @@ GirFFI.setup :GLib
|
|
5
5
|
|
6
6
|
require 'ffi-glib/array'
|
7
7
|
require 'ffi-glib/byte_array'
|
8
|
+
require 'ffi-glib/bytes'
|
9
|
+
require 'ffi-glib/error'
|
8
10
|
require 'ffi-glib/hash_table'
|
9
11
|
require 'ffi-glib/iconv'
|
10
12
|
require 'ffi-glib/list'
|
@@ -31,6 +33,9 @@ module GLib
|
|
31
33
|
attach_function :g_byte_array_new, [], :pointer
|
32
34
|
attach_function :g_byte_array_append, [:pointer, :pointer, :uint], :pointer
|
33
35
|
|
36
|
+
attach_function :g_bytes_get_data, [:pointer, :pointer], :pointer
|
37
|
+
attach_function :g_bytes_new, [:pointer, :size_t], :pointer
|
38
|
+
|
34
39
|
attach_function :g_array_new, [:int, :int, :uint], :pointer
|
35
40
|
attach_function :g_array_append_vals, [:pointer, :pointer, :uint], :pointer
|
36
41
|
attach_function :g_array_get_element_size, [:pointer], :uint
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GLib
|
2
|
+
load_class :Bytes
|
3
|
+
|
4
|
+
# Overrides for GBytes, GLib's immutable array of bytes.
|
5
|
+
class Bytes
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
remove_method :get_data if method_defined? :get_data
|
9
|
+
|
10
|
+
# Override for GBytes#get_data, needed due to mis-identification of the
|
11
|
+
# element-type of the resulting sized array.
|
12
|
+
def get_data
|
13
|
+
length_ptr = GirFFI::InOutPointer.for :gsize
|
14
|
+
data_ptr = Lib.g_bytes_get_data self, length_ptr
|
15
|
+
length = length_ptr.to_value
|
16
|
+
GirFFI::SizedArray.wrap(:guint8, length, data_ptr)
|
17
|
+
end
|
18
|
+
|
19
|
+
def each &block
|
20
|
+
data.each(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from it
|
24
|
+
case it
|
25
|
+
when self
|
26
|
+
it
|
27
|
+
when FFI::Pointer
|
28
|
+
wrap it
|
29
|
+
else
|
30
|
+
new it
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
undef new
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.new arr
|
39
|
+
data = GirFFI::SizedArray.from :guint8, arr.size, arr
|
40
|
+
self.wrap Lib.g_bytes_new data.to_ptr, data.size
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def data
|
46
|
+
@data ||= get_data
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module GLib
|
2
|
+
load_class :Error
|
3
|
+
|
4
|
+
# Overrides for GError, used by GLib for handling non-fatal errors.
|
5
|
+
class Error
|
6
|
+
# TODO: Auto-convert strings and symbols to quarks
|
7
|
+
GIR_FFI_DOMAIN = GLib.quark_from_string("gir_ffi")
|
8
|
+
|
9
|
+
def self.from_exception ex
|
10
|
+
new_literal GIR_FFI_DOMAIN, 0, ex.message
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from it
|
14
|
+
from_exception it
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/ffi-gobject/value.rb
CHANGED
@@ -123,8 +123,11 @@ module GObject
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def get_enum_enhanced
|
126
|
-
|
127
|
-
|
126
|
+
current_gtype_class.wrap(get_enum)
|
127
|
+
end
|
128
|
+
|
129
|
+
def current_gtype_class
|
130
|
+
GirFFI::Builder.build_by_gtype(current_gtype)
|
128
131
|
end
|
129
132
|
|
130
133
|
def check_type_compatibility val
|
@@ -140,7 +143,7 @@ module GObject
|
|
140
143
|
when TYPE_HASH_TABLE
|
141
144
|
GLib::HashTable.wrap [:gpointer, :gpointer], boxed
|
142
145
|
else
|
143
|
-
boxed.
|
146
|
+
current_gtype_class.wrap(boxed) unless boxed.null?
|
144
147
|
end
|
145
148
|
end
|
146
149
|
|
@@ -2,16 +2,16 @@ module GObjectIntrospection
|
|
2
2
|
# Wraps a GIConstantInfo struct; represents a constant.
|
3
3
|
class IConstantInfo < IBaseInfo
|
4
4
|
TYPE_TAG_TO_UNION_MEMBER = {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
5
|
+
gint8: :v_int8,
|
6
|
+
gint16: :v_int16,
|
7
|
+
gint32: :v_int32,
|
8
|
+
gint64: :v_int64,
|
9
|
+
guint8: :v_uint8,
|
10
|
+
guint16: :v_uint16,
|
11
|
+
guint32: :v_uint32,
|
12
|
+
guint64: :v_uint64,
|
13
|
+
gdouble: :v_double,
|
14
|
+
utf8: :v_string
|
15
15
|
}
|
16
16
|
|
17
17
|
def value_union
|
@@ -31,27 +31,27 @@ module GObjectIntrospection
|
|
31
31
|
class IRepository
|
32
32
|
# Map info type to class. Default is IBaseInfo.
|
33
33
|
TYPEMAP = {
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
34
|
+
invalid: IBaseInfo,
|
35
|
+
function: IFunctionInfo,
|
36
|
+
callback: ICallbackInfo,
|
37
|
+
struct: IStructInfo,
|
38
38
|
# TODO: There's no GIBoxedInfo, so what does :boxed mean?
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
39
|
+
boxed: IBaseInfo,
|
40
|
+
enum: IEnumInfo,
|
41
|
+
flags: IFlagsInfo,
|
42
|
+
object: IObjectInfo,
|
43
|
+
interface: IInterfaceInfo,
|
44
|
+
constant: IConstantInfo,
|
45
|
+
invalid_was_error_domain: IBaseInfo,
|
46
|
+
union: IUnionInfo,
|
47
|
+
value: IValueInfo,
|
48
|
+
signal: ISignalInfo,
|
49
|
+
vfunc: IVFuncInfo,
|
50
|
+
property: IPropertyInfo,
|
51
|
+
field: IFieldInfo,
|
52
|
+
arg: IArgInfo,
|
53
|
+
type: ITypeInfo,
|
54
|
+
unresolved: IBaseInfo
|
55
55
|
}
|
56
56
|
|
57
57
|
def initialize
|
@@ -5,12 +5,19 @@ module GObjectIntrospection
|
|
5
5
|
def flags
|
6
6
|
Lib.g_vfunc_info_get_flags @gobj
|
7
7
|
end
|
8
|
+
|
9
|
+
def throws?
|
10
|
+
flags & 8 != 0
|
11
|
+
end
|
12
|
+
|
8
13
|
def offset
|
9
14
|
Lib.g_vfunc_info_get_offset @gobj
|
10
15
|
end
|
16
|
+
|
11
17
|
def signal
|
12
18
|
ISignalInfo.wrap(Lib.g_vfunc_info_get_signal @gobj)
|
13
19
|
end
|
20
|
+
|
14
21
|
def invoker
|
15
22
|
IFunctionInfo.wrap(Lib.g_vfunc_info_get_invoker @gobj)
|
16
23
|
end
|
@@ -210,13 +210,7 @@ module GObjectIntrospection
|
|
210
210
|
|
211
211
|
# IVFuncInfo
|
212
212
|
|
213
|
-
|
214
|
-
:must_chain_up, (1 << 0),
|
215
|
-
:must_override, (1 << 1),
|
216
|
-
:must_not_override, (1 << 2)
|
217
|
-
]
|
218
|
-
|
219
|
-
attach_function :g_vfunc_info_get_flags, [:pointer], :IVFuncInfoFlags
|
213
|
+
attach_function :g_vfunc_info_get_flags, [:pointer], :int
|
220
214
|
attach_function :g_vfunc_info_get_offset, [:pointer], :int
|
221
215
|
attach_function :g_vfunc_info_get_signal, [:pointer], :pointer
|
222
216
|
attach_function :g_vfunc_info_get_invoker, [:pointer], :pointer
|
data/lib/gir_ffi/arg_helper.rb
CHANGED
@@ -1,9 +1,30 @@
|
|
1
1
|
require 'gir_ffi/allocation_helper'
|
2
2
|
require 'gir_ffi/builder'
|
3
|
+
require 'gir_ffi/glib_error'
|
3
4
|
|
4
5
|
module GirFFI
|
5
6
|
module ArgHelper
|
6
|
-
|
7
|
+
class ObjectStore
|
8
|
+
def initialize
|
9
|
+
@store = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def store(ptr, obj)
|
13
|
+
@store[ptr.address] = obj
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch(ptr)
|
17
|
+
return if ptr.null?
|
18
|
+
key = ptr.address
|
19
|
+
if @store.has_key? key
|
20
|
+
@store[key]
|
21
|
+
else
|
22
|
+
ptr
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
OBJECT_STORE = ObjectStore.new
|
7
28
|
|
8
29
|
def self.ptr_to_utf8_length ptr, len
|
9
30
|
ptr.null? ? nil : ptr.read_string(len)
|
@@ -11,7 +32,7 @@ module GirFFI
|
|
11
32
|
|
12
33
|
def self.check_error errpp
|
13
34
|
err = GLib::Error.wrap(errpp.read_pointer)
|
14
|
-
raise err
|
35
|
+
raise GLibError, err if err
|
15
36
|
end
|
16
37
|
|
17
38
|
def self.check_fixed_array_size size, arr, name
|
@@ -63,13 +63,27 @@ module GirFFI
|
|
63
63
|
|
64
64
|
def output_value
|
65
65
|
base = "#{callarg}.to_value"
|
66
|
-
if
|
66
|
+
if needs_out_conversion?
|
67
67
|
CToRubyConvertor.new(@type_info, base, length_argument_name).conversion
|
68
|
+
elsif allocated_by_them?
|
69
|
+
"GirFFI::InOutPointer.new(#{type_info.tag_or_class[1].inspect}, #{base}).to_value"
|
68
70
|
else
|
69
71
|
base
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
75
|
+
def needs_out_conversion?
|
76
|
+
@type_info.needs_c_to_ruby_conversion_for_functions?
|
77
|
+
end
|
78
|
+
|
79
|
+
# Check if an out argument needs to be allocated by them, the callee. Since
|
80
|
+
# caller_allocates is false by default, we must also check that the type
|
81
|
+
# is a pointer. For example, an out parameter of type gint8* will always
|
82
|
+
# be allocated by the caller (that's us).
|
83
|
+
def allocated_by_them?
|
84
|
+
!@arginfo.caller_allocates? && @type_info.pointer?
|
85
|
+
end
|
86
|
+
|
73
87
|
def length_argument_name
|
74
88
|
length_arg && length_arg.post_converted_name
|
75
89
|
end
|
@@ -21,9 +21,7 @@ module GirFFI
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def capture_variable_name
|
24
|
-
if direction == :out
|
25
|
-
@capture_variable_name ||= new_variable
|
26
|
-
end
|
24
|
+
result_name if direction == :out
|
27
25
|
end
|
28
26
|
|
29
27
|
def pre_conversion
|
@@ -32,12 +30,24 @@ module GirFFI
|
|
32
30
|
[ "#{pre_converted_name} = #{pre_convertor.conversion}" ]
|
33
31
|
when :out
|
34
32
|
[ "#{pre_converted_name} = #{out_parameter_preparation}" ]
|
33
|
+
when :error
|
34
|
+
[
|
35
|
+
"#{pre_converted_name} = #{out_parameter_preparation}",
|
36
|
+
"begin"
|
37
|
+
]
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
41
|
def post_conversion
|
39
|
-
|
40
|
-
|
42
|
+
case direction
|
43
|
+
when :out
|
44
|
+
[ outgoing_post_conversion ]
|
45
|
+
when :error
|
46
|
+
[
|
47
|
+
"rescue => #{result_name}",
|
48
|
+
outgoing_post_conversion,
|
49
|
+
"end"
|
50
|
+
]
|
41
51
|
else
|
42
52
|
[]
|
43
53
|
end
|
@@ -45,10 +55,14 @@ module GirFFI
|
|
45
55
|
|
46
56
|
private
|
47
57
|
|
58
|
+
def result_name
|
59
|
+
@result_name ||= new_variable
|
60
|
+
end
|
61
|
+
|
48
62
|
def pre_convertor
|
49
63
|
@pre_convertor ||= if is_closure
|
50
64
|
ClosureConvertor.new(method_argument_name)
|
51
|
-
elsif type_info.
|
65
|
+
elsif type_info.needs_c_to_ruby_conversion_for_callbacks?
|
52
66
|
CToRubyConvertor.new(type_info,
|
53
67
|
method_argument_name,
|
54
68
|
length_argument_name)
|
@@ -57,8 +71,36 @@ module GirFFI
|
|
57
71
|
end
|
58
72
|
end
|
59
73
|
|
74
|
+
def outgoing_post_conversion
|
75
|
+
"#{pre_converted_name}.set_value #{outgoing_convertor.conversion}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def outgoing_convertor
|
79
|
+
@outgoing_convertor ||= if type_info.needs_ruby_to_c_conversion_for_callbacks?
|
80
|
+
RubyToCConvertor.new(type_info, result_name)
|
81
|
+
else
|
82
|
+
NullConvertor.new(result_name)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
60
86
|
def out_parameter_preparation
|
61
|
-
|
87
|
+
type_spec = type_info.tag_or_class
|
88
|
+
if allocated_by_us?
|
89
|
+
"GirFFI::InOutPointer.new(#{type_spec[1].inspect})" +
|
90
|
+
".tap { |ptr| #{method_argument_name}.put_pointer 0, ptr }"
|
91
|
+
else
|
92
|
+
"GirFFI::InOutPointer.new(#{type_spec.inspect}, #{method_argument_name})"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Check if an out argument needs to be allocated by us, the callee. Since
|
97
|
+
# caller_allocates is false by default, we must also check that the type
|
98
|
+
# is a pointer. For example, an out parameter of type gint8* will always
|
99
|
+
# be allocate by the caller.
|
100
|
+
def allocated_by_us?
|
101
|
+
!@arginfo.caller_allocates? &&
|
102
|
+
type_info.pointer? &&
|
103
|
+
![:object, :zero_terminated].include?(specialized_type_tag)
|
62
104
|
end
|
63
105
|
|
64
106
|
def length_argument_name
|