fiddley 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5efaacddbd8392ed670102f7b62b32fe2a6024c
4
+ data.tar.gz: 20a196def56f4a803388c342ad513832fd7632ff
5
+ SHA512:
6
+ metadata.gz: 231465cbe7a2a2a87ca7dc43b0186d8f0df8d044b9ae0ab0ea0ea76c11d99ac9a622444739501bd7536233a6eb77c20be99c51f9e406dd9f61440f812dfbf083
7
+ data.tar.gz: 924b4785615ba80370947d36fa9c7263e38cd763fd63c2198cf23a56a9a6847fb4770f9ba60130a397592a6484e4ae358d8b2f847d61ac6bd791285822e4b9e8
@@ -0,0 +1,38 @@
1
+ Fiddley
2
+ =======
3
+
4
+ Ruby-FFI compatible API layer for Fiddle.
5
+
6
+
7
+ Status
8
+ ------
9
+
10
+ Under development.
11
+
12
+
13
+
14
+ License
15
+ -------
16
+
17
+ Copyright (c) 2017 NAKAMURA Usaku usa@garbagecollect.jp
18
+
19
+ Redistribution and use in source and binary forms, with or without
20
+ modification, are permitted provided that the following conditions are met:
21
+
22
+ 1. Redistributions of source code must retain the above copyright notice,
23
+ this list of conditions and the following disclaimer.
24
+ 2. Redistributions in binary form must reproduce the above copyright notice,
25
+ this list of conditions and the following disclaimer in the documentation
26
+ and/or other materials provided with the distribution.
27
+
28
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
29
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
32
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
+
@@ -0,0 +1,10 @@
1
+ # -*- Ruby -*-
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask.rb"
4
+
5
+ task :default => :test
6
+
7
+ desc "Run all tests"
8
+ task :test do
9
+ ruby "-Ilib test/sample.rb"
10
+ end
@@ -0,0 +1,20 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "fiddley"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fiddley"
7
+ spec.version = Fiddley::VERSION
8
+ spec.authors = ["U.Nakamura"]
9
+ spec.email = ["usa@garbagecollect.jp"]
10
+
11
+ spec.summary = "FFI compatible interface for Fiddle"
12
+ spec.description = "Use Fiddle instead of Ruby-FFI !!!"
13
+ spec.homepage = "https://github.com/unak/fiddley"
14
+ spec.license = "BSD-2-Clause"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^tmp/|^tools/|^examples/|^\.}) }
17
+ spec.bindir = "bin"
18
+ spec.executables = []
19
+ spec.require_paths = ["lib"]
20
+ end
@@ -0,0 +1 @@
1
+ require "fiddley"
@@ -0,0 +1,11 @@
1
+ module Fiddley
2
+ VERSION = "0.0.1"
3
+ end
4
+
5
+ FFI = Fiddley
6
+
7
+ require "fiddley/function"
8
+ require "fiddley/memory_pointer"
9
+ require "fiddley/library"
10
+ require "fiddley/struct"
11
+ require "fiddley/utils"
@@ -0,0 +1,13 @@
1
+ require "fiddle/import"
2
+
3
+ module Fiddley
4
+ class Function
5
+ def initialize(ret, params, blk)
6
+ Module.new do
7
+ extend Fiddle::Importer
8
+ dlload Fiddley::Library::LIBC
9
+ @@func = bind("#{Fiddley.type2str(ret)} callback(#{params.map{|e|Fiddley.type2str(e)}.join(', ')})", &blk)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,97 @@
1
+ require "fiddle/import"
2
+
3
+ module Fiddley
4
+ module Library
5
+ include Fiddle::Importer
6
+ alias ffi_lib dlload
7
+
8
+ def extended(mod)
9
+ @convention = nil
10
+ end
11
+
12
+ def attach_function(rname, cname, params, ret = nil, blocking: false)
13
+ if ret.nil?
14
+ ret = params
15
+ params = cname
16
+ cname = rname
17
+ end
18
+ extern "#{Fiddley.type2str(ret)} #{cname}(#{params.map{|e| Fiddley.type2str(e)}.join(', ')})", @convention
19
+ if cname != rname
20
+ instance_eval <<-end
21
+ alias #{rname.inspect} #{cname.inspect}
22
+ end
23
+ end
24
+ end
25
+
26
+ def ffi_convention(conv)
27
+ @convention = conv
28
+ end
29
+
30
+ case RUBY_PLATFORM
31
+ when /cygwin/
32
+ libc_so = "cygwin1.dll"
33
+ libm_so = "cygwin1.dll"
34
+ when /linux/
35
+ libdir = '/lib'
36
+ case [0].pack('L!').size
37
+ when 4
38
+ # 32-bit ruby
39
+ libdir = '/lib32' if File.directory? '/lib32'
40
+ when 8
41
+ # 64-bit ruby
42
+ libdir = '/lib64' if File.directory? '/lib64'
43
+ end
44
+ libc_so = File.join(libdir, "libc.so.6")
45
+ libm_so = File.join(libdir, "libm.so.6")
46
+ when /mingw/, /mswin/
47
+ require "rbconfig"
48
+ crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'
49
+ libc_so = libm_so = "#{crtname}.dll"
50
+ when /darwin/
51
+ libc_so = "/usr/lib/libc.dylib"
52
+ libm_so = "/usr/lib/libm.dylib"
53
+ when /kfreebsd/
54
+ libc_so = "/lib/libc.so.0.1"
55
+ libm_so = "/lib/libm.so.1"
56
+ when /gnu/ #GNU/Hurd
57
+ libc_so = "/lib/libc.so.0.3"
58
+ libm_so = "/lib/libm.so.6"
59
+ when /mirbsd/
60
+ libc_so = "/usr/lib/libc.so.41.10"
61
+ libm_so = "/usr/lib/libm.so.7.0"
62
+ when /freebsd/
63
+ libc_so = "/lib/libc.so.7"
64
+ libm_so = "/lib/libm.so.5"
65
+ when /bsd|dragonfly/
66
+ libc_so = "/usr/lib/libc.so"
67
+ libm_so = "/usr/lib/libm.so"
68
+ when /solaris/
69
+ libdir = '/lib'
70
+ case [0].pack('L!').size
71
+ when 4
72
+ # 32-bit ruby
73
+ libdir = '/lib' if File.directory? '/lib'
74
+ when 8
75
+ # 64-bit ruby
76
+ libdir = '/lib/64' if File.directory? '/lib/64'
77
+ end
78
+ libc_so = File.join(libdir, "libc.so")
79
+ libm_so = File.join(libdir, "libm.so")
80
+ end
81
+
82
+ libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
83
+ libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
84
+
85
+ if !libc_so || !libm_so
86
+ ruby = EnvUtil.rubybin
87
+ ldd = `ldd #{ruby}`
88
+ #puts ldd
89
+ libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
90
+ libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
91
+ #p [libc_so, libm_so]
92
+ end
93
+
94
+ LIBC = libc_so
95
+ LIBM = libm_so
96
+ end
97
+ end
@@ -0,0 +1,85 @@
1
+ require "fiddle/import"
2
+
3
+ module Fiddley
4
+ class MemoryPointer
5
+ def initialize(type, num = 1)
6
+ size = Fiddley.type2size(type) * num
7
+ @ptr = Fiddle::Pointer.malloc(size)
8
+ end
9
+
10
+ def write_int16(val)
11
+ @ptr[0, 2] = [val].pack('s')
12
+ end
13
+
14
+ def write_int32(val)
15
+ @ptr[0, 4] = [val].pack('l')
16
+ end
17
+
18
+ def write_array_of_uint32(ary)
19
+ write_string(ary.pack('L*'))
20
+ end
21
+
22
+ def write_string(str)
23
+ @ptr[0, str.bytesize] = str
24
+ end
25
+
26
+ def read_bytes(size)
27
+ @ptr[0, size]
28
+ end
29
+
30
+ def read_int8
31
+ get_int8(0)
32
+ end
33
+
34
+ def read_uint8
35
+ get_uint8(0)
36
+ end
37
+
38
+ def read_int16
39
+ get_int16(0)
40
+ end
41
+
42
+ def read_uint16
43
+ get_uint16(0)
44
+ end
45
+
46
+ def read_int32
47
+ get_int32(0)
48
+ end
49
+
50
+ def read_uint32
51
+ get_uint32(0)
52
+ end
53
+
54
+ def get_int8(offset)
55
+ @ptr[offset, 1].unpack1('c')
56
+ end
57
+
58
+ def get_uint8(offset)
59
+ @ptr[offset, 1].unpack1('C')
60
+ end
61
+
62
+ def get_int16(offset)
63
+ @ptr[offset, 2].unpack1('s')
64
+ end
65
+
66
+ def get_uint16(offset)
67
+ @ptr[offset, 2].unpack1('S')
68
+ end
69
+
70
+ def get_int32(offset)
71
+ @ptr[offset, 4].unpack1('l')
72
+ end
73
+
74
+ def get_uint32(offset)
75
+ @ptr[offset, 4].unpack1('L')
76
+ end
77
+
78
+ alias read_int read_int32
79
+ alias get_int get_int32
80
+
81
+ def to_ptr
82
+ @ptr
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,52 @@
1
+ require "fiddle/import"
2
+
3
+ module Fiddley
4
+ class Struct
5
+ def self.layout(*args)
6
+ @members = {}
7
+ @size = 0
8
+ args.each_slice(2) do |name, type|
9
+ @members[name] = [type, @size]
10
+ @size += Fiddley.type2size(type)
11
+ end
12
+ end
13
+
14
+ def self.ptr
15
+ :pointer
16
+ end
17
+
18
+ def self.members
19
+ @members
20
+ end
21
+
22
+ def self.size
23
+ @size
24
+ end
25
+
26
+ def self.offset_of(key)
27
+ raise IndexError, "#{key} is not defined" unless members.has_key?(key)
28
+ type, offset = members[key]
29
+ offset
30
+ end
31
+
32
+ def initialize
33
+ @ptr = Fiddle::Pointer.malloc(self.class.size)
34
+ end
35
+
36
+ def [](key)
37
+ raise IndexError, "#{key} is not defined" unless self.class.members.has_key?(key)
38
+ type, offset = self.class.members[key]
39
+ Fiddley.str2value(type, @ptr[offset, Fiddley.type2size(type)])
40
+ end
41
+
42
+ def []=(key, value)
43
+ raise IndexError, "#{key} is not defined" unless self.class.members.has_key?(key)
44
+ type, offset = self.class.members[key]
45
+ @ptr[offset, Fiddley.type2size(type)] = Fiddley.value2str(type, value)
46
+ end
47
+
48
+ def to_ptr
49
+ @ptr
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,81 @@
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}"
16
+ end
17
+ end
18
+
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}"
33
+ end
34
+ end
35
+
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}"
50
+ end
51
+ end
52
+
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
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,9 @@
1
+ require "ffi"
2
+
3
+ module Hello
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ attach_function :puts, [:string], :int
7
+ end
8
+
9
+ Hello.puts("Hello, world")
@@ -0,0 +1,13 @@
1
+ require 'ffi'
2
+
3
+ module HelloWin
4
+ extend FFI::Library
5
+
6
+ ffi_lib 'user32'
7
+ ffi_convention :stdcall
8
+
9
+ attach_function :message_box, :MessageBoxA,[ :pointer, :string, :string, :uint ], :int
10
+ end
11
+
12
+ rc = HelloWin.message_box nil, 'Hello Windows!', 'FFI on Windows', 1
13
+ puts "Return code: #{rc}"
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fiddley
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - U.Nakamura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Use Fiddle instead of Ruby-FFI !!!
14
+ email:
15
+ - usa@garbagecollect.jp
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - Rakefile
22
+ - fiddley.gemspec
23
+ - lib/ffi.rb
24
+ - lib/fiddley.rb
25
+ - lib/fiddley/function.rb
26
+ - lib/fiddley/library.rb
27
+ - lib/fiddley/memory_pointer.rb
28
+ - lib/fiddley/struct.rb
29
+ - lib/fiddley/utils.rb
30
+ - test/sample.rb
31
+ - test/sample2.rb
32
+ homepage: https://github.com/unak/fiddley
33
+ licenses:
34
+ - BSD-2-Clause
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 2.6.11
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: FFI compatible interface for Fiddle
56
+ test_files: []