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 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: