gir_ffi 0.7.3 → 0.7.4
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.
- 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
|