ffi-extra 0.0.1.1 → 0.0.2
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.
- data/lib/ffi/extra.rb +138 -117
- metadata +2 -2
data/lib/ffi/extra.rb
CHANGED
@@ -10,122 +10,143 @@
|
|
10
10
|
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
11
|
#++
|
12
12
|
|
13
|
-
class Integer
|
14
|
-
def to_ffi
|
15
|
-
self
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class String
|
20
|
-
def to_ffi
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class NilClass
|
26
|
-
def to_ffi
|
27
|
-
self
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
13
|
module FFI
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
14
|
+
def self.type_size (type)
|
15
|
+
type = FFI.find_type(type) if type.is_a?(Symbol)
|
16
|
+
|
17
|
+
if type.is_a?(Type::Builtin) || type.is_a?(Class) && type.ancestors.member?(FFI::Struct) || type.ancestors.member?(FFI::ManagedStruct)
|
18
|
+
type.size
|
19
|
+
elsif type.respond_to? :from_native
|
20
|
+
type.native_type.size
|
21
|
+
else
|
22
|
+
raise ArgumentError, 'you have to pass a Struct, a Builtin type or a Symbol'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Library
|
27
|
+
def ffi_lib_add (*names)
|
28
|
+
ffi_lib *((begin
|
29
|
+
ffi_libraries
|
30
|
+
rescue Exception
|
31
|
+
[]
|
32
|
+
end).map {|lib|
|
33
|
+
lib.name
|
34
|
+
} + names).compact.uniq.reject {|lib|
|
35
|
+
lib == '[current process]'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_function? (sym, libraries=nil)
|
40
|
+
libraries ||= ffi_libraries
|
41
|
+
|
42
|
+
libraries.any? {|lib|
|
43
|
+
if lib.is_a?(DynamicLibrary)
|
44
|
+
lib
|
45
|
+
else
|
46
|
+
DynamicLibrary.new(lib, 0)
|
47
|
+
end.find_function(sym.to_s) rescue nil
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def attach_function! (*args, &block)
|
52
|
+
begin
|
53
|
+
attach_function(*args, &block)
|
54
|
+
rescue Exception => e
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Type::Builtin
|
61
|
+
def name
|
62
|
+
inspect[/:(\w+) /][1 .. -2]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Pointer
|
67
|
+
def read (type)
|
68
|
+
if type.is_a?(Symbol)
|
69
|
+
if respond_to? "read_#{type}"
|
70
|
+
return send "read_#{type}"
|
71
|
+
else
|
72
|
+
type = FFI.find_type(type)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
if type.is_a?(Type::Builtin)
|
77
|
+
send "read_#{type.name.downcase}"
|
78
|
+
elsif type.is_a?(Class) && type.ancestors.member?(FFI::Struct) && !type.ancestors.member?(FFI::ManagedStruct)
|
79
|
+
type.new(self)
|
80
|
+
elsif type.respond_to? :from_native
|
81
|
+
type.from_native(typecast(type.native_type), nil)
|
82
|
+
else
|
83
|
+
raise ArgumentError, 'you have to pass a Struct, a Builtin type or a Symbol'
|
84
|
+
end
|
85
|
+
end; alias typecast read
|
86
|
+
|
87
|
+
def write (what, type=nil)
|
88
|
+
if type
|
89
|
+
if respond_to? "write_#{type.downcase}"
|
90
|
+
send "write_#{type.downcase}", what
|
91
|
+
else
|
92
|
+
write_bytes what, what.size
|
93
|
+
end
|
94
|
+
else
|
95
|
+
case what
|
96
|
+
when FFI::Struct then write_bytes what.pointer.read_bytes(what.size)
|
97
|
+
when String then write_bytes what
|
98
|
+
else raise ArgumentError, 'I do not know how to deal with this variable'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def read_array_of (number, type)
|
104
|
+
if type.is_a?(Symbol)
|
105
|
+
if respond_to? "read_array_of_#{type.downcase}"
|
106
|
+
return send "read_array_of_#{type.downcase}", number
|
107
|
+
else
|
108
|
+
type = FFI.find_type(type)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
type = type.native_type if type.respond_to? :native_type
|
113
|
+
|
114
|
+
if type.is_a?(Class) && type.ancestors.member?(FFI::Struct)
|
115
|
+
read_array_of_pointer(number).map {|pointer|
|
116
|
+
type.new(pointer)
|
117
|
+
}
|
118
|
+
else
|
119
|
+
begin
|
120
|
+
send "read_array_of_#{type.name.downcase}", number
|
121
|
+
rescue NameError
|
122
|
+
raise ArgumentError, "#{type.name} is not supported"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def write_array_of (type, data)
|
128
|
+
if type.is_a?(Symbol)
|
129
|
+
if respond_to? "write_array_of_#{type}"
|
130
|
+
return send "write_array_of_#{type}", data
|
131
|
+
else
|
132
|
+
type = FFI.find_type(type)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
type = type.native_type if type.respond_to? :native_type
|
137
|
+
|
138
|
+
if type.is_a?(Class) && type.ancestors.member?(FFI::Struct)
|
139
|
+
write_array_of_pointer(data)
|
140
|
+
else
|
141
|
+
begin
|
142
|
+
send "write_array_of_#{type.name.downcase}", data
|
143
|
+
rescue NameError
|
144
|
+
raise ArgumentError, "#{type.name} is not supported"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
find_type(:size_t) rescue typedef(:ulong, :size_t)
|
151
|
+
find_type(:ssize_t) rescue typedef(:long, :ssize_t)
|
131
152
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ffi-extra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- meh.
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-09-
|
13
|
+
date: 2011-09-11 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ffi
|