ffi 1.9.21 → 1.9.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +22 -0
- data/.gitmodules +3 -0
- data/.travis.yml +52 -0
- data/.yardopts +5 -0
- data/Gemfile +15 -0
- data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
- data/README.md +1 -1
- data/Rakefile +28 -3
- data/appveyor.yml +22 -0
- data/ext/ffi_c/Call.c +1 -22
- data/ext/ffi_c/Call.h +0 -9
- data/ext/ffi_c/Closure.c +54 -0
- data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
- data/ext/ffi_c/Function.c +16 -25
- data/ext/ffi_c/Function.h +1 -2
- data/ext/ffi_c/FunctionInfo.c +0 -4
- data/ext/ffi_c/MethodHandle.c +33 -268
- data/ext/ffi_c/extconf.rb +3 -3
- data/ext/ffi_c/ffi.c +2 -2
- data/ext/ffi_c/libffi.bsd.mk +3 -3
- data/ext/ffi_c/libffi.darwin.mk +1 -1
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +2 -2
- data/ext/ffi_c/libffi.vc.mk +1 -1
- data/ext/ffi_c/libffi.vc64.mk +1 -1
- data/ext/ffi_c/libffi/.appveyor.yml +48 -0
- data/ext/ffi_c/libffi/.gitignore +36 -0
- data/ext/ffi_c/libffi/.travis.yml +30 -0
- data/ext/ffi_c/libffi/.travis/install.sh +14 -0
- data/ext/ffi_c/libffi/Makefile.am +5 -3
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/autogen.sh +1 -1
- data/ext/ffi_c/libffi/config.guess +1466 -0
- data/ext/ffi_c/libffi/config.sub +1836 -0
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +15 -3
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
- data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/closures.c +143 -97
- data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
- data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
- data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
- data/ffi.gemspec +14 -1
- data/lib/ffi/library.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +7 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +76 -0
- data/samples/qsort.rb +21 -0
- data/samples/sample_helper.rb +6 -0
- metadata +59 -81
- metadata.gz.sig +0 -0
- data/ext/ffi_c/ClosurePool.c +0 -283
- data/gen/Rakefile +0 -30
- data/libtest/Benchmark.c +0 -52
- data/libtest/BoolTest.c +0 -34
- data/libtest/BufferTest.c +0 -31
- data/libtest/ClosureTest.c +0 -205
- data/libtest/EnumTest.c +0 -51
- data/libtest/FunctionTest.c +0 -70
- data/libtest/GNUmakefile +0 -149
- data/libtest/GlobalVariable.c +0 -62
- data/libtest/LastErrorTest.c +0 -21
- data/libtest/NumberTest.c +0 -132
- data/libtest/PointerTest.c +0 -63
- data/libtest/ReferenceTest.c +0 -23
- data/libtest/StringTest.c +0 -34
- data/libtest/StructTest.c +0 -243
- data/libtest/UnionTest.c +0 -43
- data/libtest/VariadicTest.c +0 -99
- data/spec/ffi/async_callback_spec.rb +0 -35
- data/spec/ffi/bitmask_spec.rb +0 -575
- data/spec/ffi/bool_spec.rb +0 -32
- data/spec/ffi/buffer_spec.rb +0 -279
- data/spec/ffi/callback_spec.rb +0 -773
- data/spec/ffi/custom_param_type.rb +0 -37
- data/spec/ffi/custom_type_spec.rb +0 -74
- data/spec/ffi/dup_spec.rb +0 -52
- data/spec/ffi/enum_spec.rb +0 -423
- data/spec/ffi/errno_spec.rb +0 -20
- data/spec/ffi/ffi_spec.rb +0 -28
- data/spec/ffi/fixtures/Benchmark.c +0 -52
- data/spec/ffi/fixtures/BitmaskTest.c +0 -51
- data/spec/ffi/fixtures/BoolTest.c +0 -34
- data/spec/ffi/fixtures/BufferTest.c +0 -31
- data/spec/ffi/fixtures/ClosureTest.c +0 -205
- data/spec/ffi/fixtures/EnumTest.c +0 -51
- data/spec/ffi/fixtures/FunctionTest.c +0 -142
- data/spec/ffi/fixtures/GNUmakefile +0 -149
- data/spec/ffi/fixtures/GlobalVariable.c +0 -62
- data/spec/ffi/fixtures/LastErrorTest.c +0 -21
- data/spec/ffi/fixtures/NumberTest.c +0 -132
- data/spec/ffi/fixtures/PipeHelper.h +0 -21
- data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
- data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
- data/spec/ffi/fixtures/PointerTest.c +0 -63
- data/spec/ffi/fixtures/ReferenceTest.c +0 -23
- data/spec/ffi/fixtures/StringTest.c +0 -34
- data/spec/ffi/fixtures/StructTest.c +0 -243
- data/spec/ffi/fixtures/UnionTest.c +0 -43
- data/spec/ffi/fixtures/VariadicTest.c +0 -99
- data/spec/ffi/fixtures/classes.rb +0 -438
- data/spec/ffi/function_spec.rb +0 -97
- data/spec/ffi/io_spec.rb +0 -16
- data/spec/ffi/library_spec.rb +0 -286
- data/spec/ffi/long_double.rb +0 -30
- data/spec/ffi/managed_struct_spec.rb +0 -68
- data/spec/ffi/memorypointer_spec.rb +0 -78
- data/spec/ffi/number_spec.rb +0 -247
- data/spec/ffi/platform_spec.rb +0 -114
- data/spec/ffi/pointer_spec.rb +0 -285
- data/spec/ffi/rbx/attach_function_spec.rb +0 -34
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
- data/spec/ffi/rbx/spec_helper.rb +0 -6
- data/spec/ffi/rbx/struct_spec.rb +0 -18
- data/spec/ffi/spec_helper.rb +0 -93
- data/spec/ffi/string_spec.rb +0 -118
- data/spec/ffi/strptr_spec.rb +0 -50
- data/spec/ffi/struct_by_ref_spec.rb +0 -43
- data/spec/ffi/struct_callback_spec.rb +0 -69
- data/spec/ffi/struct_initialize_spec.rb +0 -35
- data/spec/ffi/struct_packed_spec.rb +0 -50
- data/spec/ffi/struct_spec.rb +0 -882
- data/spec/ffi/typedef_spec.rb +0 -91
- data/spec/ffi/union_spec.rb +0 -67
- data/spec/ffi/variadic_spec.rb +0 -132
- data/spec/spec.opts +0 -4
@@ -1,78 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This file is part of ruby-ffi.
|
3
|
-
# For licensing, see LICENSE.SPECS
|
4
|
-
#
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
|
8
|
-
MemoryPointer = FFI::MemoryPointer
|
9
|
-
|
10
|
-
describe "MemoryPointer#total" do
|
11
|
-
it "MemoryPointer.new(:char, 1).total == 1" do
|
12
|
-
expect(MemoryPointer.new(:char, 1).total).to eq 1
|
13
|
-
end
|
14
|
-
|
15
|
-
it "MemoryPointer.new(:short, 1).total == 2" do
|
16
|
-
expect(MemoryPointer.new(:short, 1).total).to eq 2
|
17
|
-
end
|
18
|
-
|
19
|
-
it "MemoryPointer.new(:int, 1).total == 4" do
|
20
|
-
expect(MemoryPointer.new(:int, 1).total).to eq 4
|
21
|
-
end
|
22
|
-
|
23
|
-
it "MemoryPointer.new(:long_long, 1).total == 8" do
|
24
|
-
expect(MemoryPointer.new(:long_long, 1).total).to eq 8
|
25
|
-
end
|
26
|
-
|
27
|
-
it "MemoryPointer.new(1024).total == 1024" do
|
28
|
-
expect(MemoryPointer.new(1024).total).to eq 1024
|
29
|
-
end
|
30
|
-
end
|
31
|
-
describe "MemoryPointer#read_array_of_long" do
|
32
|
-
it "foo" do
|
33
|
-
ptr = MemoryPointer.new(:long, 1024)
|
34
|
-
ptr[0].write_long 1234
|
35
|
-
ptr[1].write_long 5678
|
36
|
-
l = ptr.read_array_of_long(2)
|
37
|
-
expect(l[0]).to eq 1234
|
38
|
-
expect(l[1]).to eq 5678
|
39
|
-
end
|
40
|
-
end
|
41
|
-
describe "MemoryPointer argument" do
|
42
|
-
module Ptr
|
43
|
-
extend FFI::Library
|
44
|
-
ffi_lib FFI::Platform::LIBC
|
45
|
-
attach_function :memset, [ :pointer, :int, :ulong ], :pointer
|
46
|
-
attach_function :memcpy, [ :pointer, :pointer, :ulong ], :pointer
|
47
|
-
end
|
48
|
-
|
49
|
-
it "Pointer passed correctly" do
|
50
|
-
p = MemoryPointer.new :int, 1
|
51
|
-
ret = Ptr.memset(p, 0, p.total)
|
52
|
-
expect(ret).to eq p
|
53
|
-
end
|
54
|
-
|
55
|
-
it "Data passed to native function" do
|
56
|
-
p = MemoryPointer.new :int, 1
|
57
|
-
p2 = MemoryPointer.new :int, 1
|
58
|
-
p2.put_int(0, 0x5eadbeef)
|
59
|
-
Ptr.memcpy(p, p2, p.total)
|
60
|
-
expect(p.get_int(0)).to eq p2.get_int(0)
|
61
|
-
expect(p2.get_int(0)).not_to eql 0
|
62
|
-
end
|
63
|
-
end
|
64
|
-
describe "MemoryPointer return value" do
|
65
|
-
module Stdio
|
66
|
-
extend FFI::Library
|
67
|
-
ffi_lib FFI::Platform::LIBC
|
68
|
-
attach_function :fopen, [ :string, :string ], :pointer
|
69
|
-
attach_function :fclose, [ :pointer ], :int
|
70
|
-
attach_function :fwrite, [ :pointer, :ulong, :ulong, :string ], :ulong
|
71
|
-
end
|
72
|
-
|
73
|
-
it "fopen returns non-nil" do
|
74
|
-
fp = Stdio.fopen("/dev/null", "w")
|
75
|
-
expect(fp).to_not be_nil
|
76
|
-
expect(Stdio.fclose(fp)).to eq 0 unless fp.nil? or fp.null?
|
77
|
-
end
|
78
|
-
end
|
data/spec/ffi/number_spec.rb
DELETED
@@ -1,247 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This file is part of ruby-ffi.
|
3
|
-
# For licensing, see LICENSE.SPECS
|
4
|
-
#
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
|
8
|
-
describe "Function with primitive integer arguments" do
|
9
|
-
module LibTest
|
10
|
-
extend FFI::Library
|
11
|
-
ffi_lib TestLibrary::PATH
|
12
|
-
attach_function :ret_s8, [ :char ], :char
|
13
|
-
attach_function :ret_u8, [ :uchar ], :uchar
|
14
|
-
attach_function :ret_s16, [ :short ], :short
|
15
|
-
attach_function :ret_u16, [ :ushort ], :ushort
|
16
|
-
attach_function :ret_s32, [ :int ], :int
|
17
|
-
attach_function :ret_u32, [ :uint ], :uint
|
18
|
-
attach_function :ret_s64, [ :long_long ], :long_long
|
19
|
-
attach_function :ret_u64, [ :ulong_long ], :ulong_long
|
20
|
-
attach_function :ret_long, [ :long ], :long
|
21
|
-
attach_function :ret_ulong, [ :ulong ], :ulong
|
22
|
-
attach_function :set_s8, [ :char ], :void
|
23
|
-
attach_function :get_s8, [ ], :char
|
24
|
-
attach_function :set_float, [ :float ], :void
|
25
|
-
attach_function :get_float, [ ], :float
|
26
|
-
attach_function :set_double, [ :double ], :void
|
27
|
-
attach_function :get_double, [ ], :double
|
28
|
-
end
|
29
|
-
|
30
|
-
it "int8.size" do
|
31
|
-
expect(FFI::TYPE_INT8.size).to eq(1)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "uint8.size" do
|
35
|
-
expect(FFI::TYPE_UINT8.size).to eq(1)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "int16.size" do
|
39
|
-
expect(FFI::TYPE_INT16.size).to eq(2)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "uint16.size" do
|
43
|
-
expect(FFI::TYPE_UINT16.size).to eq(2)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "int32.size" do
|
47
|
-
expect(FFI::TYPE_INT32.size).to eq(4)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "uint32.size" do
|
51
|
-
expect(FFI::TYPE_UINT32.size).to eq(4)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "int64.size" do
|
55
|
-
expect(FFI::TYPE_INT64.size).to eq(8)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "uint64.size" do
|
59
|
-
expect(FFI::TYPE_UINT64.size).to eq(8)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "float.size" do
|
63
|
-
expect(FFI::TYPE_FLOAT32.size).to eq(4)
|
64
|
-
end
|
65
|
-
|
66
|
-
it "double.size" do
|
67
|
-
expect(FFI::TYPE_FLOAT64.size).to eq(8)
|
68
|
-
end
|
69
|
-
[ 0, 127, -128, -1 ].each do |i|
|
70
|
-
it ":char call(:char (#{i}))" do
|
71
|
-
expect(LibTest.ret_s8(i)).to eq(i)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
[ 0, 0x7f, 0x80, 0xff ].each do |i|
|
75
|
-
it ":uchar call(:uchar (#{i}))" do
|
76
|
-
expect(LibTest.ret_u8(i)).to eq(i)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
[ 0, 0x7fff, -0x8000, -1 ].each do |i|
|
80
|
-
it ":short call(:short (#{i}))" do
|
81
|
-
expect(LibTest.ret_s16(i)).to eq(i)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
[ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
|
85
|
-
it ":ushort call(:ushort (#{i}))" do
|
86
|
-
expect(LibTest.ret_u16(i)).to eq(i)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
90
|
-
it ":int call(:int (#{i}))" do
|
91
|
-
expect(LibTest.ret_s32(i)).to eq(i)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
95
|
-
it ":uint call(:uint (#{i}))" do
|
96
|
-
expect(LibTest.ret_u32(i)).to eq(i)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
|
100
|
-
it ":long_long call(:long_long (#{i}))" do
|
101
|
-
expect(LibTest.ret_s64(i)).to eq(i)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
105
|
-
it ":ulong_long call(:ulong_long (#{i}))" do
|
106
|
-
expect(LibTest.ret_u64(i)).to eq(i)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
if FFI::Platform::LONG_SIZE == 32
|
110
|
-
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
111
|
-
it ":long call(:long (#{i}))" do
|
112
|
-
expect(LibTest.ret_long(i)).to eq(i)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
116
|
-
it ":ulong call(:ulong (#{i}))" do
|
117
|
-
expect(LibTest.ret_ulong(i)).to eq(i)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
else
|
121
|
-
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
|
122
|
-
it ":long call(:long (#{i}))" do
|
123
|
-
expect(LibTest.ret_long(i)).to eq(i)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
127
|
-
it ":ulong call(:ulong (#{i}))" do
|
128
|
-
expect(LibTest.ret_ulong(i)).to eq(i)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
[ 0.0, 0.1, 1.1, 1.23 ].each do |f|
|
132
|
-
it ":float call(:double (#{f}))" do
|
133
|
-
LibTest.set_float(f)
|
134
|
-
expect((LibTest.get_float - f).abs).to be < 0.001
|
135
|
-
end
|
136
|
-
end
|
137
|
-
[ 0.0, 0.1, 1.1, 1.23 ].each do |f|
|
138
|
-
it ":double call(:double (#{f}))" do
|
139
|
-
LibTest.set_double(f)
|
140
|
-
expect((LibTest.get_double - f).abs).to be < 0.001
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
describe "Integer parameter range checking" do
|
146
|
-
[ 128, -129 ].each do |i|
|
147
|
-
it ":char call(:char (#{i}))" do
|
148
|
-
expect { expect(LibTest.ret_int8_t(i)).to eq(i) }.to raise_error
|
149
|
-
end
|
150
|
-
end
|
151
|
-
[ -1, 256 ].each do |i|
|
152
|
-
it ":uchar call(:uchar (#{i}))" do
|
153
|
-
expect { expect(LibTest.ret_u_int8_t(i)).to eq(i) }.to raise_error
|
154
|
-
end
|
155
|
-
end
|
156
|
-
[ 0x8000, -0x8001 ].each do |i|
|
157
|
-
it ":short call(:short (#{i}))" do
|
158
|
-
expect { expect(LibTest.ret_int16_t(i)).to eq(i) }.to raise_error
|
159
|
-
end
|
160
|
-
end
|
161
|
-
[ -1, 0x10000 ].each do |i|
|
162
|
-
it ":ushort call(:ushort (#{i}))" do
|
163
|
-
expect { expect(LibTest.ret_u_int16_t(i)).to eq(i) }.to raise_error
|
164
|
-
end
|
165
|
-
end
|
166
|
-
[ 0x80000000, -0x80000001 ].each do |i|
|
167
|
-
it ":int call(:int (#{i}))" do
|
168
|
-
expect { expect(LibTest.ret_int32_t(i)).to eq(i) }.to raise_error
|
169
|
-
end
|
170
|
-
end
|
171
|
-
[ -1, 0x100000000 ].each do |i|
|
172
|
-
it ":ushort call(:ushort (#{i}))" do
|
173
|
-
expect { expect(LibTest.ret_u_int32_t(i)).to eq(i) }.to raise_error
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
describe "Three different size Integer arguments" do
|
178
|
-
TYPE_MAP = {
|
179
|
-
's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort,
|
180
|
-
's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long,
|
181
|
-
'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double
|
182
|
-
}
|
183
|
-
TYPES = TYPE_MAP.keys
|
184
|
-
module LibTest
|
185
|
-
extend FFI::Library
|
186
|
-
ffi_lib TestLibrary::PATH
|
187
|
-
|
188
|
-
|
189
|
-
[ 's32', 'u32', 's64', 'u64' ].each do |rt|
|
190
|
-
TYPES.each do |t1|
|
191
|
-
TYPES.each do |t2|
|
192
|
-
TYPES.each do |t3|
|
193
|
-
begin
|
194
|
-
attach_function "pack_#{t1}#{t2}#{t3}_#{rt}",
|
195
|
-
[ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void
|
196
|
-
rescue FFI::NotFoundError
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
PACK_VALUES = {
|
205
|
-
's8' => [ 0x12 ],
|
206
|
-
'u8' => [ 0x34 ],
|
207
|
-
's16' => [ 0x5678 ],
|
208
|
-
'u16' => [ 0x9abc ],
|
209
|
-
's32' => [ 0x7654321f ],
|
210
|
-
'u32' => [ 0xfee1babe ],
|
211
|
-
'sL' => [ 0x1f2e3d4c ],
|
212
|
-
'uL' => [ 0xf7e8d9ca ],
|
213
|
-
's64' => [ 0x1eafdeadbeefa1b2 ],
|
214
|
-
# 'f32' => [ 1.234567 ],
|
215
|
-
'f64' => [ 9.87654321 ]
|
216
|
-
}
|
217
|
-
|
218
|
-
def verify(p, off, t, v)
|
219
|
-
if t == 'f32'
|
220
|
-
expect(p.get_float32(off)).to eq(v)
|
221
|
-
elsif t == 'f64'
|
222
|
-
expect(p.get_float64(off)).to eq(v)
|
223
|
-
else
|
224
|
-
expect(p.get_int64(off)).to eq(v)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
PACK_VALUES.keys.each do |t1|
|
229
|
-
PACK_VALUES.keys.each do |t2|
|
230
|
-
PACK_VALUES.keys.each do |t3|
|
231
|
-
PACK_VALUES[t1].each do |v1|
|
232
|
-
PACK_VALUES[t2].each do |v2|
|
233
|
-
PACK_VALUES[t3].each do |v3|
|
234
|
-
it "call(#{TYPE_MAP[t1]} (#{v1}), #{TYPE_MAP[t2]} (#{v2}), #{TYPE_MAP[t3]} (#{v3}))" do
|
235
|
-
p = FFI::Buffer.new :long_long, 3
|
236
|
-
LibTest.send("pack_#{t1}#{t2}#{t3}_s64", v1, v2, v3, p)
|
237
|
-
verify(p, 0, t1, v1)
|
238
|
-
verify(p, 8, t2, v2)
|
239
|
-
verify(p, 16, t3, v3)
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
data/spec/ffi/platform_spec.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This file is part of ruby-ffi.
|
3
|
-
# For licensing, see LICENSE.SPECS
|
4
|
-
#
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
|
8
|
-
describe "FFI::Platform::LIBSUFFIX" do
|
9
|
-
case OS
|
10
|
-
when "linux"
|
11
|
-
it "returns 'so'" do
|
12
|
-
expect(FFI::Platform::LIBSUFFIX).to eq('so')
|
13
|
-
end
|
14
|
-
when "windows"
|
15
|
-
it "returns 'dll'" do
|
16
|
-
expect(FFI::Platform::LIBSUFFIX).to eq('dll')
|
17
|
-
end
|
18
|
-
when "darwin"
|
19
|
-
it "returns 'dylib'" do
|
20
|
-
expect(FFI::Platform::LIBSUFFIX).to eq('dylib')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "FFI::Platform::IS_WINDOWS" do
|
26
|
-
case OS
|
27
|
-
when "linux"
|
28
|
-
it "returns false" do
|
29
|
-
expect(FFI::Platform::IS_WINDOWS).to be false
|
30
|
-
end
|
31
|
-
when "windows"
|
32
|
-
it "returns true" do
|
33
|
-
expect(FFI::Platform::IS_WINDOWS).to be true
|
34
|
-
end
|
35
|
-
when "darwin"
|
36
|
-
it "returns false" do
|
37
|
-
expect(FFI::Platform::IS_WINDOWS).to be false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "FFI::Platform::ARCH" do
|
43
|
-
it "returns the architecture type" do
|
44
|
-
expect(FFI::Platform::ARCH).to eq(CPU)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe "FFI::Platform::OS" do
|
49
|
-
case OS
|
50
|
-
when "linux"
|
51
|
-
it "returns 'linux' as a string" do
|
52
|
-
expect(FFI::Platform::OS).to eq('linux')
|
53
|
-
end
|
54
|
-
when "windows"
|
55
|
-
it "returns 'windows' as a string" do
|
56
|
-
expect(FFI::Platform::OS).to eq('windows')
|
57
|
-
end
|
58
|
-
when "darwin"
|
59
|
-
it "returns 'darwin' as a string" do
|
60
|
-
expect(FFI::Platform::OS).to eq('darwin')
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "FFI::Platform.windows?" do
|
66
|
-
case OS
|
67
|
-
when "linux"
|
68
|
-
it "returns false" do
|
69
|
-
expect(FFI::Platform.windows?).to be false
|
70
|
-
end
|
71
|
-
when "windows"
|
72
|
-
it "returns true" do
|
73
|
-
expect(FFI::Platform.windows?).to be true
|
74
|
-
end
|
75
|
-
when "darwin"
|
76
|
-
it "returns false" do
|
77
|
-
expect(FFI::Platform.windows?).to be false
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe "FFI::Platform.mac?" do
|
83
|
-
case OS
|
84
|
-
when "linux"
|
85
|
-
it "returns false" do
|
86
|
-
expect(FFI::Platform.mac?).to be false
|
87
|
-
end
|
88
|
-
when "windows"
|
89
|
-
it "returns false" do
|
90
|
-
expect(FFI::Platform.mac?).to be false
|
91
|
-
end
|
92
|
-
when "darwin"
|
93
|
-
it "returns true" do
|
94
|
-
expect(FFI::Platform.mac?).to be true
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
describe "FFI::Platform.unix?" do
|
100
|
-
case OS
|
101
|
-
when "linux"
|
102
|
-
it "returns true" do
|
103
|
-
expect(FFI::Platform.unix?).to be true
|
104
|
-
end
|
105
|
-
when "windows"
|
106
|
-
it "returns false" do
|
107
|
-
expect(FFI::Platform.unix?).to be false
|
108
|
-
end
|
109
|
-
when "darwin"
|
110
|
-
it "returns true" do
|
111
|
-
expect(FFI::Platform.unix?).to be true
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
data/spec/ffi/pointer_spec.rb
DELETED
@@ -1,285 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# This file is part of ruby-ffi.
|
3
|
-
# For licensing, see LICENSE.SPECS
|
4
|
-
#
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'delegate'
|
8
|
-
|
9
|
-
module PointerTestLib
|
10
|
-
extend FFI::Library
|
11
|
-
ffi_lib TestLibrary::PATH
|
12
|
-
begin
|
13
|
-
attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
|
14
|
-
rescue FFI::NotFoundError
|
15
|
-
# NetBSD uses #define instead of typedef for these
|
16
|
-
attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
|
17
|
-
end
|
18
|
-
attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
|
19
|
-
attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void
|
20
|
-
attach_function :ptr_ret_pointer, [ :pointer, :int ], :pointer
|
21
|
-
end
|
22
|
-
describe "Pointer" do
|
23
|
-
include FFI
|
24
|
-
class ToPtrTest
|
25
|
-
def initialize(ptr)
|
26
|
-
@ptr = ptr
|
27
|
-
end
|
28
|
-
def to_ptr
|
29
|
-
@ptr
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
it "Any object implementing #to_ptr can be passed as a :pointer parameter" do
|
34
|
-
memory = FFI::MemoryPointer.new :long_long
|
35
|
-
magic = 0x12345678
|
36
|
-
memory.put_int32(0, magic)
|
37
|
-
tp = ToPtrTest.new(memory)
|
38
|
-
expect(PointerTestLib.ptr_ret_int32_t(tp, 0)).to eq(magic)
|
39
|
-
end
|
40
|
-
class PointerDelegate < DelegateClass(FFI::Pointer)
|
41
|
-
def initialize(ptr)
|
42
|
-
@ptr = ptr
|
43
|
-
end
|
44
|
-
def to_ptr
|
45
|
-
@ptr
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
it "A DelegateClass(Pointer) can be passed as a :pointer parameter" do
|
50
|
-
memory = FFI::MemoryPointer.new :long_long
|
51
|
-
magic = 0x12345678
|
52
|
-
memory.put_int32(0, magic)
|
53
|
-
ptr = PointerDelegate.new(memory)
|
54
|
-
expect(PointerTestLib.ptr_ret_int32_t(ptr, 0)).to eq(magic)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "Fixnum cannot be used as a Pointer argument" do
|
58
|
-
expect { PointerTestLib.ptr_ret_int32(0, 0) }.to raise_error
|
59
|
-
end
|
60
|
-
|
61
|
-
it "Bignum cannot be used as a Pointer argument" do
|
62
|
-
expect { PointerTestLib.ptr_ret_int32(0xfee1deadbeefcafebabe, 0) }.to raise_error
|
63
|
-
end
|
64
|
-
|
65
|
-
it "#to_ptr" do
|
66
|
-
memory = FFI::MemoryPointer.new :pointer
|
67
|
-
expect(memory.to_ptr).to eq(memory)
|
68
|
-
|
69
|
-
expect(FFI::Pointer::NULL.to_ptr).to eq(FFI::Pointer::NULL)
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "pointer type methods" do
|
73
|
-
|
74
|
-
it "#read_pointer" do
|
75
|
-
memory = FFI::MemoryPointer.new :pointer
|
76
|
-
PointerTestLib.ptr_set_pointer(memory, 0, PointerTestLib.ptr_from_address(0xdeadbeef))
|
77
|
-
expect(memory.read_pointer.address).to eq(0xdeadbeef)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "#write_pointer" do
|
81
|
-
memory = FFI::MemoryPointer.new :pointer
|
82
|
-
memory.write_pointer(PointerTestLib.ptr_from_address(0xdeadbeef))
|
83
|
-
expect(PointerTestLib.ptr_ret_pointer(memory, 0).address).to eq(0xdeadbeef)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "#read_array_of_pointer" do
|
87
|
-
values = [0x12345678, 0xfeedf00d, 0xdeadbeef]
|
88
|
-
memory = FFI::MemoryPointer.new :pointer, values.size
|
89
|
-
values.each_with_index do |address, j|
|
90
|
-
PointerTestLib.ptr_set_pointer(memory, j * FFI.type_size(:pointer), PointerTestLib.ptr_from_address(address))
|
91
|
-
end
|
92
|
-
array = memory.read_array_of_pointer(values.size)
|
93
|
-
values.each_with_index do |address, j|
|
94
|
-
expect(array[j].address).to eq(address)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
describe 'NULL' do
|
101
|
-
it 'should be obtained using Pointer::NULL constant' do
|
102
|
-
null_ptr = FFI::Pointer::NULL
|
103
|
-
expect(null_ptr).to be_null
|
104
|
-
end
|
105
|
-
it 'should be obtained passing address 0 to constructor' do
|
106
|
-
expect(FFI::Pointer.new(0)).to be_null
|
107
|
-
end
|
108
|
-
it 'should raise an error when attempting read/write operations on it' do
|
109
|
-
null_ptr = FFI::Pointer::NULL
|
110
|
-
expect { null_ptr.read_int }.to raise_error(FFI::NullPointerError)
|
111
|
-
expect { null_ptr.write_int(0xff1) }.to raise_error(FFI::NullPointerError)
|
112
|
-
end
|
113
|
-
it 'returns true when compared with nil' do
|
114
|
-
expect((FFI::Pointer::NULL == nil)).to be true
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
it "Pointer.size returns sizeof pointer on platform" do
|
119
|
-
expect(FFI::Pointer.size).to eq((FFI::Platform::ADDRESS_SIZE / 8))
|
120
|
-
end
|
121
|
-
|
122
|
-
describe "#slice" do
|
123
|
-
before(:each) do
|
124
|
-
@mptr = FFI::MemoryPointer.new(:char, 12)
|
125
|
-
@mptr.put_uint(0, 0x12345678)
|
126
|
-
@mptr.put_uint(4, 0xdeadbeef)
|
127
|
-
end
|
128
|
-
|
129
|
-
it "contents of sliced pointer matches original pointer at offset" do
|
130
|
-
expect(@mptr.slice(4, 4).get_uint(0)).to eq(0xdeadbeef)
|
131
|
-
end
|
132
|
-
|
133
|
-
it "modifying sliced pointer is reflected in original pointer" do
|
134
|
-
@mptr.slice(4, 4).put_uint(0, 0xfee1dead)
|
135
|
-
expect(@mptr.get_uint(4)).to eq(0xfee1dead)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "access beyond bounds should raise IndexError" do
|
139
|
-
expect { @mptr.slice(4, 4).get_int(4) }.to raise_error(IndexError)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
describe "#type_size" do
|
144
|
-
it "should be same as FFI.type_size(type)" do
|
145
|
-
expect(FFI::MemoryPointer.new(:int, 1).type_size).to eq(FFI.type_size(:int))
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe "AutoPointer" do
|
151
|
-
loop_count = 30
|
152
|
-
wiggle_room = 5 # GC rarely cleans up all objects. we can get most of them, and that's enough to determine if the basic functionality is working.
|
153
|
-
magic = 0x12345678
|
154
|
-
|
155
|
-
class AutoPointerTestHelper
|
156
|
-
@@count = 0
|
157
|
-
def self.release
|
158
|
-
@@count += 1 if @@count > 0
|
159
|
-
end
|
160
|
-
def self.reset
|
161
|
-
@@count = 0
|
162
|
-
end
|
163
|
-
def self.gc_everything(count)
|
164
|
-
loop = 5
|
165
|
-
while @@count < count && loop > 0
|
166
|
-
loop -= 1
|
167
|
-
TestLibrary.force_gc
|
168
|
-
sleep 0.05 unless @@count == count
|
169
|
-
end
|
170
|
-
@@count = 0
|
171
|
-
end
|
172
|
-
def self.finalizer
|
173
|
-
self.method(:release).to_proc
|
174
|
-
end
|
175
|
-
end
|
176
|
-
class AutoPointerSubclass < FFI::AutoPointer
|
177
|
-
def self.release(ptr); end
|
178
|
-
end
|
179
|
-
|
180
|
-
# see #427
|
181
|
-
it "cleanup via default release method", :broken => true do
|
182
|
-
expect(AutoPointerSubclass).to receive(:release).at_least(loop_count-wiggle_room).times
|
183
|
-
AutoPointerTestHelper.reset
|
184
|
-
loop_count.times do
|
185
|
-
# note that if we called
|
186
|
-
# AutoPointerTestHelper.method(:release).to_proc inline, we'd
|
187
|
-
# have a reference to the pointer and it would never get GC'd.
|
188
|
-
AutoPointerSubclass.new(PointerTestLib.ptr_from_address(magic))
|
189
|
-
end
|
190
|
-
AutoPointerTestHelper.gc_everything loop_count
|
191
|
-
end
|
192
|
-
|
193
|
-
# see #427
|
194
|
-
it "cleanup when passed a proc", :broken => true do
|
195
|
-
# NOTE: passing a proc is touchy, because it's so easy to create a memory leak.
|
196
|
-
#
|
197
|
-
# specifically, if we made an inline call to
|
198
|
-
#
|
199
|
-
# AutoPointerTestHelper.method(:release).to_proc
|
200
|
-
#
|
201
|
-
# we'd have a reference to the pointer and it would
|
202
|
-
# never get GC'd.
|
203
|
-
expect(AutoPointerTestHelper).to receive(:release).at_least(loop_count-wiggle_room).times
|
204
|
-
AutoPointerTestHelper.reset
|
205
|
-
loop_count.times do
|
206
|
-
FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
|
207
|
-
AutoPointerTestHelper.finalizer)
|
208
|
-
end
|
209
|
-
AutoPointerTestHelper.gc_everything loop_count
|
210
|
-
end
|
211
|
-
|
212
|
-
# see #427
|
213
|
-
it "cleanup when passed a method", :broken => true do
|
214
|
-
expect(AutoPointerTestHelper).to receive(:release).at_least(loop_count-wiggle_room).times
|
215
|
-
AutoPointerTestHelper.reset
|
216
|
-
loop_count.times do
|
217
|
-
FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
|
218
|
-
AutoPointerTestHelper.method(:release))
|
219
|
-
end
|
220
|
-
AutoPointerTestHelper.gc_everything loop_count
|
221
|
-
end
|
222
|
-
|
223
|
-
it "can be used as the return type of a function" do
|
224
|
-
expect do
|
225
|
-
Module.new do
|
226
|
-
extend FFI::Library
|
227
|
-
ffi_lib TestLibrary::PATH
|
228
|
-
class CustomAutoPointer < FFI::AutoPointer
|
229
|
-
def self.release(ptr); end
|
230
|
-
end
|
231
|
-
attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], CustomAutoPointer
|
232
|
-
end
|
233
|
-
end.not_to raise_error
|
234
|
-
end
|
235
|
-
|
236
|
-
describe "#new" do
|
237
|
-
it "MemoryPointer argument raises TypeError" do
|
238
|
-
expect { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.to raise_error(::TypeError)
|
239
|
-
end
|
240
|
-
it "AutoPointer argument raises TypeError" do
|
241
|
-
expect { AutoPointerSubclass.new(AutoPointerSubclass.new(PointerTestLib.ptr_from_address(0))) }.to raise_error(::TypeError)
|
242
|
-
end
|
243
|
-
it "Buffer argument raises TypeError" do
|
244
|
-
expect { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.to raise_error(::TypeError)
|
245
|
-
end
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
describe "#autorelease?" do
|
250
|
-
ptr_class = Class.new(FFI::AutoPointer) do
|
251
|
-
def self.release(ptr); end
|
252
|
-
end
|
253
|
-
|
254
|
-
it "should be true by default" do
|
255
|
-
expect(ptr_class.new(FFI::Pointer.new(0xdeadbeef)).autorelease?).to be true
|
256
|
-
end
|
257
|
-
|
258
|
-
it "should return false when autorelease=(false)" do
|
259
|
-
ptr = ptr_class.new(FFI::Pointer.new(0xdeadbeef))
|
260
|
-
ptr.autorelease = false
|
261
|
-
expect(ptr.autorelease?).to be false
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
describe "#type_size" do
|
266
|
-
ptr_class = Class.new(FFI::AutoPointer) do
|
267
|
-
def self.release(ptr); end
|
268
|
-
end
|
269
|
-
|
270
|
-
it "type_size of AutoPointer should match wrapped Pointer" do
|
271
|
-
aptr = ptr_class.new(FFI::Pointer.new(:int, 0xdeadbeef))
|
272
|
-
expect(aptr.type_size).to eq(FFI.type_size(:int))
|
273
|
-
end
|
274
|
-
|
275
|
-
it "[] offset should match wrapped Pointer" do
|
276
|
-
mptr = FFI::MemoryPointer.new(:int, 1024)
|
277
|
-
aptr = ptr_class.new(FFI::Pointer.new(:int, mptr))
|
278
|
-
aptr[0].write_uint(0xfee1dead)
|
279
|
-
aptr[1].write_uint(0xcafebabe)
|
280
|
-
expect(mptr[0].read_uint).to eq(0xfee1dead)
|
281
|
-
expect(mptr[1].read_uint).to eq(0xcafebabe)
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|