fiddley 0.0.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.
- checksums.yaml +4 -4
- data/lib/ffi.rb +2 -0
- data/lib/fiddley.rb +1 -3
- data/lib/fiddley/function.rb +2 -1
- data/lib/fiddley/library.rb +19 -9
- data/lib/fiddley/memory_pointer.rb +100 -46
- data/lib/fiddley/struct.rb +7 -3
- data/lib/fiddley/utils.rb +134 -70
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff58c14e7eed618a4c40f23d0b962f6e4d4aac51
|
4
|
+
data.tar.gz: 84ce3629b10e1cd0d6f068f60d4c9c6891b5d0f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96a3282bf572735f15aeff0a21a472f50da36df876bcce23e8d3a1785fa8d8c06ba1be2b4eaceaa6984a4bb89968a9f9c8435fc4888266b5052964c02664a7e0
|
7
|
+
data.tar.gz: 2b9cae8442c68515937c62c0697604f9ad2b249fce6f3b4fa09aa38f9cf90499baf07fe1c433f699b3ef021ff58760b82a539e154772a7db2d4cb4b5dce54325
|
data/lib/ffi.rb
CHANGED
data/lib/fiddley.rb
CHANGED
data/lib/fiddley/function.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "fiddle/import"
|
2
|
+
require "fiddley/utils"
|
2
3
|
|
3
4
|
module Fiddley
|
4
5
|
class Function
|
@@ -6,7 +7,7 @@ module Fiddley
|
|
6
7
|
Module.new do
|
7
8
|
extend Fiddle::Importer
|
8
9
|
dlload Fiddley::Library::LIBC
|
9
|
-
@@func = bind("#{Fiddley.type2str(ret)} callback(#{params.map{|e|Fiddley.type2str(e)}.join(', ')})", &blk)
|
10
|
+
@@func = bind("#{Fiddley::Utils.type2str(ret)} callback(#{params.map{|e| Fiddley::Utils.type2str(e)}.join(', ')})", &blk)
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
data/lib/fiddley/library.rb
CHANGED
@@ -1,21 +1,37 @@
|
|
1
1
|
require "fiddle/import"
|
2
|
+
require "fiddley/utils"
|
2
3
|
|
3
4
|
module Fiddley
|
4
5
|
module Library
|
6
|
+
include Fiddley::Utils
|
5
7
|
include Fiddle::Importer
|
8
|
+
|
6
9
|
alias ffi_lib dlload
|
7
10
|
|
8
11
|
def extended(mod)
|
9
12
|
@convention = nil
|
10
13
|
end
|
11
14
|
|
15
|
+
def ffi_convention(conv)
|
16
|
+
@convention = conv
|
17
|
+
end
|
18
|
+
|
12
19
|
def attach_function(rname, cname, params, ret = nil, blocking: false)
|
13
20
|
if ret.nil?
|
14
21
|
ret = params
|
15
22
|
params = cname
|
16
23
|
cname = rname
|
17
24
|
end
|
18
|
-
extern "#{
|
25
|
+
extern "#{type2str(ret)} #{cname}(#{params.map{|e| type2str(e)}.join(', ')})", @convention
|
26
|
+
if ret == :string
|
27
|
+
tname = (cname.to_s + '+').to_sym
|
28
|
+
instance_eval <<-end
|
29
|
+
alias #{tname.inspect} #{cname.inspect}
|
30
|
+
end
|
31
|
+
define_singleton_method(cname) do |*args|
|
32
|
+
__send__(tname, *args).to_s
|
33
|
+
end
|
34
|
+
end
|
19
35
|
if cname != rname
|
20
36
|
instance_eval <<-end
|
21
37
|
alias #{rname.inspect} #{cname.inspect}
|
@@ -23,10 +39,6 @@ module Fiddley
|
|
23
39
|
end
|
24
40
|
end
|
25
41
|
|
26
|
-
def ffi_convention(conv)
|
27
|
-
@convention = conv
|
28
|
-
end
|
29
|
-
|
30
42
|
case RUBY_PLATFORM
|
31
43
|
when /cygwin/
|
32
44
|
libc_so = "cygwin1.dll"
|
@@ -83,12 +95,10 @@ module Fiddley
|
|
83
95
|
libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
|
84
96
|
|
85
97
|
if !libc_so || !libm_so
|
86
|
-
|
87
|
-
ldd = `ldd #{ruby}`
|
88
|
-
#puts ldd
|
98
|
+
require "rbconfig"
|
99
|
+
ldd = `ldd #{RbConfig.ruby}`
|
89
100
|
libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
|
90
101
|
libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
|
91
|
-
#p [libc_so, libm_so]
|
92
102
|
end
|
93
103
|
|
94
104
|
LIBC = libc_so
|
@@ -1,85 +1,139 @@
|
|
1
1
|
require "fiddle/import"
|
2
|
+
require "fiddley/utils"
|
2
3
|
|
3
4
|
module Fiddley
|
4
5
|
class MemoryPointer
|
5
|
-
|
6
|
-
|
7
|
-
@ptr = Fiddle::Pointer.malloc(size)
|
6
|
+
if defined?(Fiddley::RefineStringUnpack1)
|
7
|
+
using Fiddley::RefineStringUnpack1
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
@ptr[0, 2] = [val].pack('s')
|
12
|
-
end
|
10
|
+
include Fiddley::Utils
|
13
11
|
|
14
|
-
def
|
15
|
-
@
|
12
|
+
def initialize(type, num = 1, clear = true)
|
13
|
+
@size = type2size(type) * num
|
14
|
+
@ptr = Fiddle::Pointer.malloc(@size)
|
16
15
|
end
|
17
16
|
|
18
|
-
|
19
|
-
write_string(ary.pack('L*'))
|
20
|
-
end
|
17
|
+
attr_reader :size
|
21
18
|
|
22
|
-
def
|
23
|
-
@ptr
|
19
|
+
def to_ptr
|
20
|
+
@ptr
|
24
21
|
end
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
{8 => 'c', 16 => 's', 32 => 'l', 64 => 'q'}.each_pair do |bits, form|
|
24
|
+
bytes = bits/8
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
define_method("put_int#{bits}") do |offset, val|
|
27
|
+
@ptr[offset, bytes] = [val].pack(form)
|
28
|
+
end
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
define_method("write_int#{bits}") do |val|
|
31
|
+
__send__("put_int#{bits}", 0, val)
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method("put_array_of_int#{bits}") do |offset, ary|
|
35
|
+
put_bytes(offset, ary.pack(form + '*'))
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method("write_array_of_int#{bits}") do |ary|
|
39
|
+
__send__("put_array_of_int#{bits}", 0, ary)
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method("get_int#{bits}") do |offset|
|
43
|
+
@ptr[offset, bytes].unpack1(form)
|
44
|
+
end
|
45
|
+
|
46
|
+
define_method("read_int#{bits}") do
|
47
|
+
__send__("get_int#{bits}", 0)
|
48
|
+
end
|
49
|
+
|
50
|
+
define_method("get_array_of_int#{bits}") do |offset, num|
|
51
|
+
@ptr[offset, bytes*num].unpack1(form + '*')
|
52
|
+
end
|
53
|
+
|
54
|
+
define_method("read_array_of_int#{bits}") do |num|
|
55
|
+
__send__("get_array_of_int#{bits}", 0, num)
|
56
|
+
end
|
37
57
|
|
38
|
-
|
39
|
-
|
58
|
+
form2 = form.upcase
|
59
|
+
|
60
|
+
define_method("put_uint#{bits}") do |offset, val|
|
61
|
+
@ptr[offset, bytes] = [val].pack(form2)
|
62
|
+
end
|
63
|
+
|
64
|
+
define_method("write_uint#{bits}") do |val|
|
65
|
+
__send__("put_uint#{bits}", 0, val)
|
66
|
+
end
|
67
|
+
|
68
|
+
define_method("put_array_of_uint#{bits}") do |offset, ary|
|
69
|
+
put_bytes(offset, ary.pack(form2 + '*'))
|
70
|
+
end
|
71
|
+
|
72
|
+
define_method("write_array_of_uint#{bits}") do |ary|
|
73
|
+
__send__("put_array_of_uint#{bits}", 0, ary)
|
74
|
+
end
|
75
|
+
|
76
|
+
define_method("get_uint#{bits}") do |offset|
|
77
|
+
@ptr[offset, bytes].unpack1(form2)
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method("read_uint#{bits}") do
|
81
|
+
__send__("get_uint#{bits}", 0)
|
82
|
+
end
|
83
|
+
|
84
|
+
define_method("get_array_of_uint#{bits}") do |offset, num|
|
85
|
+
@ptr[offset, bytes*num].unpack1(form2 + '*')
|
86
|
+
end
|
87
|
+
|
88
|
+
define_method("read_array_of_uint#{bits}") do |num|
|
89
|
+
__send__("get_array_of_uint#{bits}", 0, num)
|
90
|
+
end
|
40
91
|
end
|
41
92
|
|
42
|
-
def
|
43
|
-
|
93
|
+
def put_bytes(offset, str, len = nil)
|
94
|
+
@ptr[offset, len ? len : str.bytesize] = len ? str[0, len] : str
|
44
95
|
end
|
45
96
|
|
46
|
-
def
|
47
|
-
|
97
|
+
def write_bytes(str, len = nil)
|
98
|
+
put_bytes(0, str, len)
|
48
99
|
end
|
49
100
|
|
50
|
-
def
|
51
|
-
|
101
|
+
def get_bytes(offset, len)
|
102
|
+
@ptr[offset, len]
|
52
103
|
end
|
53
104
|
|
54
|
-
def
|
55
|
-
|
105
|
+
def read_bytes(len)
|
106
|
+
get_bytes(0, len)
|
56
107
|
end
|
57
108
|
|
58
|
-
def
|
59
|
-
@ptr[offset,
|
109
|
+
def put_string(offset, str)
|
110
|
+
@ptr[offset, str.bytesize] = str
|
60
111
|
end
|
61
112
|
|
62
|
-
def
|
63
|
-
|
113
|
+
def write_string(str, len = nil)
|
114
|
+
put_string(0, len ? str[0, len] : str)
|
64
115
|
end
|
65
116
|
|
66
|
-
def
|
67
|
-
|
117
|
+
def write_string_length(str, len)
|
118
|
+
put_string(0, str[0, len])
|
68
119
|
end
|
69
120
|
|
70
|
-
def
|
71
|
-
@ptr[offset,
|
121
|
+
def get_string(offset, len = nil)
|
122
|
+
@ptr[offset, len ? len : @size - offset]
|
72
123
|
end
|
73
124
|
|
74
|
-
def
|
75
|
-
|
125
|
+
def read_string(len = nil)
|
126
|
+
get_string(0, len)
|
76
127
|
end
|
77
128
|
|
78
|
-
alias
|
129
|
+
alias put_int put_int32
|
130
|
+
alias write_int write_int32
|
79
131
|
alias get_int get_int32
|
132
|
+
alias read_int read_int32
|
80
133
|
|
81
|
-
|
82
|
-
|
83
|
-
|
134
|
+
alias put_uint put_uint32
|
135
|
+
alias write_uint write_uint32
|
136
|
+
alias get_uint get_uint32
|
137
|
+
alias read_uint read_uint32
|
84
138
|
end
|
85
139
|
end
|
data/lib/fiddley/struct.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
require "fiddle/import"
|
2
|
+
require "fiddley/utils"
|
2
3
|
|
3
4
|
module Fiddley
|
4
5
|
class Struct
|
6
|
+
include Fiddley::Utils
|
7
|
+
extend Fiddley::Utils
|
8
|
+
|
5
9
|
def self.layout(*args)
|
6
10
|
@members = {}
|
7
11
|
@size = 0
|
8
12
|
args.each_slice(2) do |name, type|
|
9
13
|
@members[name] = [type, @size]
|
10
|
-
@size +=
|
14
|
+
@size += type2size(type)
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
@@ -36,13 +40,13 @@ module Fiddley
|
|
36
40
|
def [](key)
|
37
41
|
raise IndexError, "#{key} is not defined" unless self.class.members.has_key?(key)
|
38
42
|
type, offset = self.class.members[key]
|
39
|
-
|
43
|
+
str2value(type, @ptr[offset, type2size(type)])
|
40
44
|
end
|
41
45
|
|
42
46
|
def []=(key, value)
|
43
47
|
raise IndexError, "#{key} is not defined" unless self.class.members.has_key?(key)
|
44
48
|
type, offset = self.class.members[key]
|
45
|
-
@ptr[offset,
|
49
|
+
@ptr[offset, type2size(type)] = value2str(type, value)
|
46
50
|
end
|
47
51
|
|
48
52
|
def to_ptr
|
data/lib/fiddley/utils.rb
CHANGED
@@ -1,81 +1,145 @@
|
|
1
1
|
module Fiddley
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
4
|
10
|
-
when :long, :ulong, :int64, :uint64
|
11
|
-
8
|
12
|
-
when :string, :pointer
|
13
|
-
8
|
14
|
-
else
|
15
|
-
raise TypeError, "unknown type #{type}"
|
2
|
+
unless "".respond_to?(:unpack1)
|
3
|
+
module RefineStringUnpack1
|
4
|
+
refine String do
|
5
|
+
def unpack1(arg)
|
6
|
+
unpack(arg).first
|
7
|
+
end
|
8
|
+
end
|
16
9
|
end
|
10
|
+
|
11
|
+
using RefineStringUnpack1
|
17
12
|
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
14
|
+
module Utils
|
15
|
+
# assumes short = 16bit, int = 32bit, long long = 64bit
|
16
|
+
LONG_SIZE = [0].pack('l!').bytesize
|
17
|
+
POINTER_SIZE = [nil].pack('p').bytesize
|
18
|
+
SIZET_FORMAT = POINTER_SIZE == LONG_SIZE ? 'l!' : 'q'
|
19
|
+
SIZET_TYPE = POINTER_SIZE == LONG_SIZE ? 'unsigned long' : 'unsigned long long'
|
20
|
+
|
21
|
+
module_function def type2size(type)
|
22
|
+
case type
|
23
|
+
when :char, :uchar, :int8, :uint8
|
24
|
+
1
|
25
|
+
when :short, :ushort, :int16, :uint16
|
26
|
+
2
|
27
|
+
when :int, :uint, :int32, :uint32, :bool
|
28
|
+
4
|
29
|
+
when :long, :ulong
|
30
|
+
LONG_SIZE
|
31
|
+
when :int64, :uint64, :long_long, :ulong_long
|
32
|
+
8
|
33
|
+
when :string, :pointer, :size_t
|
34
|
+
POINTER_SIZE
|
35
|
+
else
|
36
|
+
raise ArgumentError, "unknown type #{type}"
|
37
|
+
end
|
33
38
|
end
|
34
|
-
end
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
module_function def str2value(type, str)
|
41
|
+
case type
|
42
|
+
when :char, :int8
|
43
|
+
str.unpack1('c')
|
44
|
+
when :uchar, :uint8
|
45
|
+
str.unpack1('C')
|
46
|
+
when :short, :int16
|
47
|
+
str.unpack1('s')
|
48
|
+
when :ushort, :uint16
|
49
|
+
str.unpack1('S')
|
50
|
+
when :int32
|
51
|
+
str.unpack1('l')
|
52
|
+
when :uint32
|
53
|
+
str.unpack1('L')
|
54
|
+
when :int
|
55
|
+
str.unpack1('i!')
|
56
|
+
when :uint
|
57
|
+
str.unpack1('I!')
|
58
|
+
when :bool
|
59
|
+
str.unpack1('i!') != 0
|
60
|
+
when :long
|
61
|
+
str.unpack1('l!')
|
62
|
+
when :ulong
|
63
|
+
str.unpack1('L!')
|
64
|
+
when :long_long, :int64
|
65
|
+
str.unpack1('q')
|
66
|
+
when :ulong_long, :uint64
|
67
|
+
str.unpack1('Q')
|
68
|
+
when :string, :pointer
|
69
|
+
str.unpack1('p')
|
70
|
+
when :size_t
|
71
|
+
str.unpack1(SIZET_FORMAT)
|
72
|
+
else
|
73
|
+
raise ArgumentError, "unknown type #{type}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module_function def value2str(type, value)
|
78
|
+
case type
|
79
|
+
when :char, :int8
|
80
|
+
[value].pack('c')
|
81
|
+
when :uchar, :uint8
|
82
|
+
[value].pack('C')
|
83
|
+
when :short, :int16
|
84
|
+
[value].pack('s')
|
85
|
+
when :ushort, :uint16
|
86
|
+
[value].pack('S')
|
87
|
+
when :int32
|
88
|
+
[value].pack('l')
|
89
|
+
when :uint32
|
90
|
+
[value].pack('L')
|
91
|
+
when :int
|
92
|
+
[value].pack('i!')
|
93
|
+
when :uint
|
94
|
+
[value].pack('I!')
|
95
|
+
when :bool
|
96
|
+
[value ? 1 : 0].pack('i!')
|
97
|
+
when :long
|
98
|
+
[value].pack('l!')
|
99
|
+
when :ulong
|
100
|
+
[value].pack('L!')
|
101
|
+
when :long_long, :int64
|
102
|
+
[value].pack('q')
|
103
|
+
when :ulong_long, :uint64
|
104
|
+
[value].pack('Q')
|
105
|
+
when :string, :pointer
|
106
|
+
[value].pack('p')
|
107
|
+
when :size_t
|
108
|
+
[value].pack(SIZET_FORMAT)
|
109
|
+
else
|
110
|
+
raise ArgumentError, "unknown type #{type}"
|
111
|
+
end
|
50
112
|
end
|
51
|
-
end
|
52
113
|
|
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
|
-
|
114
|
+
module_function def type2str(type)
|
115
|
+
case type
|
116
|
+
when :char, :int8
|
117
|
+
"char"
|
118
|
+
when :uchar, :uint8
|
119
|
+
"unsigned char"
|
120
|
+
when :short, :int16
|
121
|
+
"short"
|
122
|
+
when :ushort, :uint16
|
123
|
+
"unsigned short"
|
124
|
+
when :int, :int32
|
125
|
+
"int"
|
126
|
+
when :uint, :uint32
|
127
|
+
"unsigned int"
|
128
|
+
when :long
|
129
|
+
"long"
|
130
|
+
when :ulong
|
131
|
+
"unsigned long"
|
132
|
+
when :long_long, :int64
|
133
|
+
"long long"
|
134
|
+
when :ulong_long, :uint64
|
135
|
+
"unsigned long long"
|
136
|
+
when :string, :pointer
|
137
|
+
"void *"
|
138
|
+
when :size_t
|
139
|
+
SIZET_TYPE
|
140
|
+
else
|
141
|
+
type.to_s
|
142
|
+
end
|
79
143
|
end
|
80
144
|
end
|
81
145
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiddley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- U.Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Use Fiddle instead of Ruby-FFI !!!
|
14
14
|
email:
|