fiddley 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e5efaacddbd8392ed670102f7b62b32fe2a6024c
4
- data.tar.gz: 20a196def56f4a803388c342ad513832fd7632ff
3
+ metadata.gz: ff58c14e7eed618a4c40f23d0b962f6e4d4aac51
4
+ data.tar.gz: 84ce3629b10e1cd0d6f068f60d4c9c6891b5d0f8
5
5
  SHA512:
6
- metadata.gz: 231465cbe7a2a2a87ca7dc43b0186d8f0df8d044b9ae0ab0ea0ea76c11d99ac9a622444739501bd7536233a6eb77c20be99c51f9e406dd9f61440f812dfbf083
7
- data.tar.gz: 924b4785615ba80370947d36fa9c7263e38cd763fd63c2198cf23a56a9a6847fb4770f9ba60130a397592a6484e4ae358d8b2f847d61ac6bd791285822e4b9e8
6
+ metadata.gz: 96a3282bf572735f15aeff0a21a472f50da36df876bcce23e8d3a1785fa8d8c06ba1be2b4eaceaa6984a4bb89968a9f9c8435fc4888266b5052964c02664a7e0
7
+ data.tar.gz: 2b9cae8442c68515937c62c0697604f9ad2b249fce6f3b4fa09aa38f9cf90499baf07fe1c433f699b3ef021ff58760b82a539e154772a7db2d4cb4b5dce54325
data/lib/ffi.rb CHANGED
@@ -1 +1,3 @@
1
1
  require "fiddley"
2
+
3
+ FFI = Fiddley
@@ -1,9 +1,7 @@
1
1
  module Fiddley
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
4
4
 
5
- FFI = Fiddley
6
-
7
5
  require "fiddley/function"
8
6
  require "fiddley/memory_pointer"
9
7
  require "fiddley/library"
@@ -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
@@ -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 "#{Fiddley.type2str(ret)} #{cname}(#{params.map{|e| Fiddley.type2str(e)}.join(', ')})", @convention
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
- ruby = EnvUtil.rubybin
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
- def initialize(type, num = 1)
6
- size = Fiddley.type2size(type) * num
7
- @ptr = Fiddle::Pointer.malloc(size)
6
+ if defined?(Fiddley::RefineStringUnpack1)
7
+ using Fiddley::RefineStringUnpack1
8
8
  end
9
9
 
10
- def write_int16(val)
11
- @ptr[0, 2] = [val].pack('s')
12
- end
10
+ include Fiddley::Utils
13
11
 
14
- def write_int32(val)
15
- @ptr[0, 4] = [val].pack('l')
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
- def write_array_of_uint32(ary)
19
- write_string(ary.pack('L*'))
20
- end
17
+ attr_reader :size
21
18
 
22
- def write_string(str)
23
- @ptr[0, str.bytesize] = str
19
+ def to_ptr
20
+ @ptr
24
21
  end
25
22
 
26
- def read_bytes(size)
27
- @ptr[0, size]
28
- end
23
+ {8 => 'c', 16 => 's', 32 => 'l', 64 => 'q'}.each_pair do |bits, form|
24
+ bytes = bits/8
29
25
 
30
- def read_int8
31
- get_int8(0)
32
- end
26
+ define_method("put_int#{bits}") do |offset, val|
27
+ @ptr[offset, bytes] = [val].pack(form)
28
+ end
33
29
 
34
- def read_uint8
35
- get_uint8(0)
36
- end
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
- def read_int16
39
- get_int16(0)
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 read_uint16
43
- get_uint16(0)
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 read_int32
47
- get_int32(0)
97
+ def write_bytes(str, len = nil)
98
+ put_bytes(0, str, len)
48
99
  end
49
100
 
50
- def read_uint32
51
- get_uint32(0)
101
+ def get_bytes(offset, len)
102
+ @ptr[offset, len]
52
103
  end
53
104
 
54
- def get_int8(offset)
55
- @ptr[offset, 1].unpack1('c')
105
+ def read_bytes(len)
106
+ get_bytes(0, len)
56
107
  end
57
108
 
58
- def get_uint8(offset)
59
- @ptr[offset, 1].unpack1('C')
109
+ def put_string(offset, str)
110
+ @ptr[offset, str.bytesize] = str
60
111
  end
61
112
 
62
- def get_int16(offset)
63
- @ptr[offset, 2].unpack1('s')
113
+ def write_string(str, len = nil)
114
+ put_string(0, len ? str[0, len] : str)
64
115
  end
65
116
 
66
- def get_uint16(offset)
67
- @ptr[offset, 2].unpack1('S')
117
+ def write_string_length(str, len)
118
+ put_string(0, str[0, len])
68
119
  end
69
120
 
70
- def get_int32(offset)
71
- @ptr[offset, 4].unpack1('l')
121
+ def get_string(offset, len = nil)
122
+ @ptr[offset, len ? len : @size - offset]
72
123
  end
73
124
 
74
- def get_uint32(offset)
75
- @ptr[offset, 4].unpack1('L')
125
+ def read_string(len = nil)
126
+ get_string(0, len)
76
127
  end
77
128
 
78
- alias read_int read_int32
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
- def to_ptr
82
- @ptr
83
- end
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
@@ -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 += Fiddley.type2size(type)
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
- Fiddley.str2value(type, @ptr[offset, Fiddley.type2size(type)])
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, Fiddley.type2size(type)] = Fiddley.value2str(type, value)
49
+ @ptr[offset, type2size(type)] = value2str(type, value)
46
50
  end
47
51
 
48
52
  def to_ptr
@@ -1,81 +1,145 @@
1
1
  module Fiddley
2
- def self.type2size(type)
3
- case type
4
- when :char, :uchar, :int8, :uint8
5
- 1
6
- when :short, :ushort, :int16, :uint16
7
- 2
8
- when :int, :uint, :int32, :uint32
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
- def self.str2value(type, str)
20
- case type
21
- when :char, :uchar, :int8, :uint8
22
- str.unpack1('c')
23
- when :short, :ushort, :int16, :uint16
24
- str.unpack1('s')
25
- when :int, :uint, :int32, :uint32
26
- str.unpack1('l')
27
- when :long, :ulong, :int64, :uint64
28
- str.unpack1('Q')
29
- when :string, :pointer
30
- str.unpack1('p')
31
- else
32
- raise TypeError, "unknown type #{type}"
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
- def self.value2str(type, value)
37
- case type
38
- when :char, :uchar, :int8, :uint8
39
- [value].pack('c')
40
- when :short, :ushort, :int16, :uint16
41
- [value].pack('s')
42
- when :int, :uint, :int32, :uint32
43
- [value].pack('l')
44
- when :long, :ulong, :int64, :uint64
45
- [value].pack('Q')
46
- when :string, :pointer
47
- [value].pack('p')
48
- else
49
- raise TypeError, "unknown type #{type}"
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
- def self.type2str(type)
54
- case type
55
- when :char, :int8
56
- "char"
57
- when :uchar, :uint8
58
- "unsigned char"
59
- when :short, :int16
60
- "short"
61
- when :ushort, :uint16
62
- "unsigned short"
63
- when :int, :int32
64
- "int"
65
- when :uint, :uint32
66
- "unsigned int"
67
- when :long, :int64
68
- "long"
69
- when :ulong, :uint64
70
- "unsigned long"
71
- when :long_long
72
- "long long"
73
- when :ulong_long
74
- "unsigned long long"
75
- when :string, :pointer
76
- "void *"
77
- else
78
- type.to_s
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.1
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-30 00:00:00.000000000 Z
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: