ffi 1.0.10 → 1.0.11
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.
- data/Rakefile +13 -13
- data/ext/ffi_c/AbstractMemory.c +1 -1
- data/ext/ffi_c/compat.h +2 -2
- data/ext/ffi_c/extconf.rb +3 -3
- data/lib/ffi/library.rb +10 -8
- data/lib/ffi/platform.rb +0 -2
- data/lib/ffi/struct.rb +1 -5
- data/lib/ffi/tools/const_generator.rb +10 -13
- data/spec/ffi/async_callback_spec.rb +2 -2
- data/spec/ffi/bool_spec.rb +6 -6
- data/spec/ffi/buffer_spec.rb +23 -23
- data/spec/ffi/callback_spec.rb +101 -102
- data/spec/ffi/custom_type_spec.rb +20 -24
- data/spec/ffi/dup_spec.rb +7 -7
- data/spec/ffi/enum_spec.rb +127 -127
- data/spec/ffi/errno_spec.rb +2 -2
- data/spec/ffi/ffi_spec.rb +3 -3
- data/spec/ffi/function_spec.rb +10 -10
- data/spec/ffi/library_spec.rb +30 -12
- data/spec/ffi/managed_struct_spec.rb +4 -4
- data/spec/ffi/number_spec.rb +40 -40
- data/spec/ffi/pointer_spec.rb +21 -24
- data/spec/ffi/rbx/memory_pointer_spec.rb +17 -17
- data/spec/ffi/rbx/struct_spec.rb +2 -2
- data/spec/ffi/spec_helper.rb +1 -1
- data/spec/ffi/string_spec.rb +9 -9
- data/spec/ffi/strptr_spec.rb +3 -3
- data/spec/ffi/struct_callback_spec.rb +7 -7
- data/spec/ffi/struct_initialize_spec.rb +2 -2
- data/spec/ffi/struct_packed_spec.rb +6 -6
- data/spec/ffi/struct_spec.rb +85 -85
- data/spec/ffi/typedef_spec.rb +4 -4
- data/spec/ffi/union_spec.rb +3 -3
- data/spec/ffi/variadic_spec.rb +17 -14
- data/tasks/rdoc.rake +1 -1
- metadata +4 -4
data/spec/ffi/library_spec.rb
CHANGED
@@ -16,8 +16,26 @@
|
|
16
16
|
|
17
17
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
18
18
|
describe "Library" do
|
19
|
+
describe "#ffi_convention" do
|
20
|
+
it "defaults to :default" do
|
21
|
+
m = Module.new do
|
22
|
+
extend FFI::Library
|
23
|
+
end
|
24
|
+
m.ffi_convention.should eq :default
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be settable" do
|
28
|
+
m = Module.new do
|
29
|
+
extend FFI::Library
|
30
|
+
end
|
31
|
+
|
32
|
+
m.ffi_convention.should eq :default
|
33
|
+
m.ffi_convention :stdcall
|
34
|
+
m.ffi_convention.should eq :stdcall
|
35
|
+
end
|
36
|
+
end
|
19
37
|
|
20
|
-
unless
|
38
|
+
unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
|
21
39
|
it "attach_function with no library specified" do
|
22
40
|
lambda {
|
23
41
|
Module.new do |m|
|
@@ -32,7 +50,7 @@ describe "Library" do
|
|
32
50
|
m.extend FFI::Library
|
33
51
|
ffi_lib FFI::Library::CURRENT_PROCESS
|
34
52
|
attach_function :getpid, [ ], :uint
|
35
|
-
end.getpid.should
|
53
|
+
end.getpid.should eq Process.pid
|
36
54
|
}.should_not raise_error
|
37
55
|
end
|
38
56
|
it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
|
@@ -41,7 +59,7 @@ describe "Library" do
|
|
41
59
|
m.extend FFI::Library
|
42
60
|
ffi_lib [ 'c', 'libc.so.6' ]
|
43
61
|
attach_function :getpid, [ ], :uint
|
44
|
-
end.getpid.should
|
62
|
+
end.getpid.should eq Process.pid
|
45
63
|
}.should_not raise_error
|
46
64
|
end
|
47
65
|
it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
|
@@ -50,7 +68,7 @@ describe "Library" do
|
|
50
68
|
m.extend FFI::Library
|
51
69
|
ffi_lib [ 'libc.so.6', 'c' ]
|
52
70
|
attach_function :getpid, [ ], :uint
|
53
|
-
end.getpid.should
|
71
|
+
end.getpid.should eq Process.pid
|
54
72
|
}.should_not raise_error
|
55
73
|
end
|
56
74
|
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
|
@@ -59,7 +77,7 @@ describe "Library" do
|
|
59
77
|
m.extend FFI::Library
|
60
78
|
ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
|
61
79
|
attach_function :getpid, [ ], :uint
|
62
|
-
end.getpid.should
|
80
|
+
end.getpid.should eq Process.pid
|
63
81
|
}.should_not raise_error
|
64
82
|
end
|
65
83
|
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
|
@@ -68,7 +86,7 @@ describe "Library" do
|
|
68
86
|
m.extend FFI::Library
|
69
87
|
ffi_lib 'libfubar.so.0xdeadbeef'
|
70
88
|
attach_function :getpid, [ ], :uint
|
71
|
-
end.getpid.should
|
89
|
+
end.getpid.should eq Process.pid
|
72
90
|
}.should raise_error(LoadError)
|
73
91
|
end
|
74
92
|
end
|
@@ -85,10 +103,10 @@ describe "Library" do
|
|
85
103
|
def gvar_test(name, type, val)
|
86
104
|
lib = gvar_lib(name, type)
|
87
105
|
lib.set(val)
|
88
|
-
lib.gvar.should
|
106
|
+
lib.gvar.should eq val
|
89
107
|
lib.set(0)
|
90
108
|
lib.gvar = val
|
91
|
-
lib.get.should
|
109
|
+
lib.get.should eq val
|
92
110
|
end
|
93
111
|
[ 0, 127, -128, -1 ].each do |i|
|
94
112
|
it ":char variable" do
|
@@ -157,10 +175,10 @@ describe "Library" do
|
|
157
175
|
lib = gvar_lib("pointer", :pointer)
|
158
176
|
val = FFI::MemoryPointer.new :long
|
159
177
|
lib.set(val)
|
160
|
-
lib.gvar.should
|
178
|
+
lib.gvar.should eq val
|
161
179
|
lib.set(nil)
|
162
180
|
lib.gvar = val
|
163
|
-
lib.get.should
|
181
|
+
lib.get.should eq val
|
164
182
|
end
|
165
183
|
|
166
184
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
@@ -180,11 +198,11 @@ describe "Library" do
|
|
180
198
|
val = GlobalStruct.new
|
181
199
|
val[:data] = i
|
182
200
|
lib.set(val)
|
183
|
-
lib.gvar[:data].should
|
201
|
+
lib.gvar[:data].should eq i
|
184
202
|
val[:data] = 0
|
185
203
|
lib.gvar[:data] = i
|
186
204
|
val = GlobalStruct.new(lib.get)
|
187
|
-
val[:data].should
|
205
|
+
val[:data].should eq i
|
188
206
|
end
|
189
207
|
end
|
190
208
|
end
|
@@ -19,14 +19,14 @@ require 'java' if RUBY_PLATFORM =~ /java/
|
|
19
19
|
|
20
20
|
describe "Managed Struct" do
|
21
21
|
include FFI
|
22
|
-
module
|
22
|
+
module ManagedStructTestLib
|
23
23
|
extend FFI::Library
|
24
24
|
ffi_lib TestLibrary::PATH
|
25
25
|
attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
|
26
26
|
end
|
27
27
|
it "should raise an error if release() is not defined" do
|
28
28
|
class NoRelease < FFI::ManagedStruct ; layout :i, :int; end
|
29
|
-
lambda { NoRelease.new(
|
29
|
+
lambda { NoRelease.new(ManagedStructTestLib.ptr_from_address(0x12345678)) }.should raise_error(NoMethodError)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should be the right class" do
|
@@ -36,7 +36,7 @@ describe "Managed Struct" do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
WhatClassAmI.new(
|
39
|
+
WhatClassAmI.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class.should eq WhatClassAmI
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should release memory properly" do
|
@@ -65,7 +65,7 @@ describe "Managed Struct" do
|
|
65
65
|
|
66
66
|
PleaseReleaseMe.should_receive(:release).at_least(loop_count-wiggle_room).times
|
67
67
|
loop_count.times do
|
68
|
-
|
68
|
+
PleaseReleaseMe.new(ManagedStructTestLib.ptr_from_address(0x12345678))
|
69
69
|
end
|
70
70
|
PleaseReleaseMe.wait_gc loop_count
|
71
71
|
end
|
data/spec/ffi/number_spec.rb
CHANGED
@@ -37,95 +37,95 @@ describe "Function with primitive integer arguments" do
|
|
37
37
|
attach_function :get_double, [ ], :double
|
38
38
|
end
|
39
39
|
it "int8.size" do
|
40
|
-
FFI::TYPE_INT8.size.should
|
40
|
+
FFI::TYPE_INT8.size.should eq 1
|
41
41
|
end
|
42
42
|
it "uint8.size" do
|
43
|
-
FFI::TYPE_UINT8.size.should
|
43
|
+
FFI::TYPE_UINT8.size.should eq 1
|
44
44
|
end
|
45
45
|
it "int16.size" do
|
46
|
-
FFI::TYPE_INT16.size.should
|
46
|
+
FFI::TYPE_INT16.size.should eq 2
|
47
47
|
end
|
48
48
|
it "uint16.size" do
|
49
|
-
FFI::TYPE_UINT16.size.should
|
49
|
+
FFI::TYPE_UINT16.size.should eq 2
|
50
50
|
end
|
51
51
|
it "int32.size" do
|
52
|
-
FFI::TYPE_INT32.size.should
|
52
|
+
FFI::TYPE_INT32.size.should eq 4
|
53
53
|
end
|
54
54
|
it "uint32.size" do
|
55
|
-
FFI::TYPE_UINT32.size.should
|
55
|
+
FFI::TYPE_UINT32.size.should eq 4
|
56
56
|
end
|
57
57
|
it "int64.size" do
|
58
|
-
FFI::TYPE_INT64.size.should
|
58
|
+
FFI::TYPE_INT64.size.should eq 8
|
59
59
|
end
|
60
60
|
it "uint64.size" do
|
61
|
-
FFI::TYPE_UINT64.size.should
|
61
|
+
FFI::TYPE_UINT64.size.should eq 8
|
62
62
|
end
|
63
63
|
it "float.size" do
|
64
|
-
FFI::TYPE_FLOAT32.size.should
|
64
|
+
FFI::TYPE_FLOAT32.size.should eq 4
|
65
65
|
end
|
66
66
|
it "double.size" do
|
67
|
-
FFI::TYPE_FLOAT64.size.should
|
67
|
+
FFI::TYPE_FLOAT64.size.should eq 8
|
68
68
|
end
|
69
69
|
[ 0, 127, -128, -1 ].each do |i|
|
70
70
|
it ":char call(:char (#{i}))" do
|
71
|
-
LibTest.ret_s8(i).should
|
71
|
+
LibTest.ret_s8(i).should eq i
|
72
72
|
end
|
73
73
|
end
|
74
74
|
[ 0, 0x7f, 0x80, 0xff ].each do |i|
|
75
75
|
it ":uchar call(:uchar (#{i}))" do
|
76
|
-
LibTest.ret_u8(i).should
|
76
|
+
LibTest.ret_u8(i).should eq i
|
77
77
|
end
|
78
78
|
end
|
79
79
|
[ 0, 0x7fff, -0x8000, -1 ].each do |i|
|
80
80
|
it ":short call(:short (#{i}))" do
|
81
|
-
LibTest.ret_s16(i).should
|
81
|
+
LibTest.ret_s16(i).should eq i
|
82
82
|
end
|
83
83
|
end
|
84
84
|
[ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
|
85
85
|
it ":ushort call(:ushort (#{i}))" do
|
86
|
-
LibTest.ret_u16(i).should
|
86
|
+
LibTest.ret_u16(i).should eq i
|
87
87
|
end
|
88
88
|
end
|
89
89
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
90
90
|
it ":int call(:int (#{i}))" do
|
91
|
-
LibTest.ret_s32(i).should
|
91
|
+
LibTest.ret_s32(i).should eq i
|
92
92
|
end
|
93
93
|
end
|
94
94
|
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
95
95
|
it ":uint call(:uint (#{i}))" do
|
96
|
-
LibTest.ret_u32(i).should
|
96
|
+
LibTest.ret_u32(i).should eq i
|
97
97
|
end
|
98
98
|
end
|
99
99
|
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
|
100
100
|
it ":long_long call(:long_long (#{i}))" do
|
101
|
-
LibTest.ret_s64(i).should
|
101
|
+
LibTest.ret_s64(i).should eq i
|
102
102
|
end
|
103
103
|
end
|
104
104
|
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
105
105
|
it ":ulong_long call(:ulong_long (#{i}))" do
|
106
|
-
LibTest.ret_u64(i).should
|
106
|
+
LibTest.ret_u64(i).should eq i
|
107
107
|
end
|
108
108
|
end
|
109
109
|
if FFI::Platform::LONG_SIZE == 32
|
110
110
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
111
111
|
it ":long call(:long (#{i}))" do
|
112
|
-
LibTest.ret_long(i).should
|
112
|
+
LibTest.ret_long(i).should eq i
|
113
113
|
end
|
114
114
|
end
|
115
115
|
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
116
116
|
it ":ulong call(:ulong (#{i}))" do
|
117
|
-
LibTest.ret_ulong(i).should
|
117
|
+
LibTest.ret_ulong(i).should eq i
|
118
118
|
end
|
119
119
|
end
|
120
120
|
else
|
121
121
|
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
|
122
122
|
it ":long call(:long (#{i}))" do
|
123
|
-
LibTest.ret_long(i).should
|
123
|
+
LibTest.ret_long(i).should eq i
|
124
124
|
end
|
125
125
|
end
|
126
126
|
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
127
127
|
it ":ulong call(:ulong (#{i}))" do
|
128
|
-
LibTest.ret_ulong(i).should
|
128
|
+
LibTest.ret_ulong(i).should eq i
|
129
129
|
end
|
130
130
|
end
|
131
131
|
[ 0.0, 0.1, 1.1, 1.23 ].each do |f|
|
@@ -145,32 +145,32 @@ end
|
|
145
145
|
describe "Integer parameter range checking" do
|
146
146
|
[ 128, -129 ].each do |i|
|
147
147
|
it ":char call(:char (#{i}))" do
|
148
|
-
lambda { LibTest.ret_int8_t(i).should
|
148
|
+
lambda { LibTest.ret_int8_t(i).should eq i }.should raise_error
|
149
149
|
end
|
150
150
|
end
|
151
151
|
[ -1, 256 ].each do |i|
|
152
152
|
it ":uchar call(:uchar (#{i}))" do
|
153
|
-
lambda { LibTest.ret_u_int8_t(i).should
|
153
|
+
lambda { LibTest.ret_u_int8_t(i).should eq i }.should raise_error
|
154
154
|
end
|
155
155
|
end
|
156
156
|
[ 0x8000, -0x8001 ].each do |i|
|
157
157
|
it ":short call(:short (#{i}))" do
|
158
|
-
lambda { LibTest.ret_int16_t(i).should
|
158
|
+
lambda { LibTest.ret_int16_t(i).should eq i }.should raise_error
|
159
159
|
end
|
160
160
|
end
|
161
161
|
[ -1, 0x10000 ].each do |i|
|
162
162
|
it ":ushort call(:ushort (#{i}))" do
|
163
|
-
lambda { LibTest.ret_u_int16_t(i).should
|
163
|
+
lambda { LibTest.ret_u_int16_t(i).should eq i }.should raise_error
|
164
164
|
end
|
165
165
|
end
|
166
166
|
[ 0x80000000, -0x80000001 ].each do |i|
|
167
167
|
it ":int call(:int (#{i}))" do
|
168
|
-
lambda { LibTest.ret_int32_t(i).should
|
168
|
+
lambda { LibTest.ret_int32_t(i).should eq i }.should raise_error
|
169
169
|
end
|
170
170
|
end
|
171
171
|
[ -1, 0x100000000 ].each do |i|
|
172
172
|
it ":ushort call(:ushort (#{i}))" do
|
173
|
-
lambda { LibTest.ret_u_int32_t(i).should
|
173
|
+
lambda { LibTest.ret_u_int32_t(i).should eq i }.should raise_error
|
174
174
|
end
|
175
175
|
end
|
176
176
|
end
|
@@ -214,17 +214,17 @@ describe "Three different size Integer arguments" do
|
|
214
214
|
# 'f32' => [ 1.234567 ],
|
215
215
|
'f64' => [ 9.87654321 ]
|
216
216
|
}
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end
|
217
|
+
|
218
|
+
def verify(p, off, t, v)
|
219
|
+
if t == 'f32'
|
220
|
+
p.get_float32(off).should eq v
|
221
|
+
elsif t == 'f64'
|
222
|
+
p.get_float64(off).should eq v
|
223
|
+
else
|
224
|
+
p.get_int64(off).should eq v
|
226
225
|
end
|
227
226
|
end
|
227
|
+
|
228
228
|
PACK_VALUES.keys.each do |t1|
|
229
229
|
PACK_VALUES.keys.each do |t2|
|
230
230
|
PACK_VALUES.keys.each do |t3|
|
@@ -234,9 +234,9 @@ describe "Three different size Integer arguments" do
|
|
234
234
|
it "call(#{TYPE_MAP[t1]} (#{v1}), #{TYPE_MAP[t2]} (#{v2}), #{TYPE_MAP[t3]} (#{v3}))" do
|
235
235
|
p = FFI::Buffer.new :long_long, 3
|
236
236
|
LibTest.send("pack_#{t1}#{t2}#{t3}_s64", v1, v2, v3, p)
|
237
|
-
|
238
|
-
|
239
|
-
|
237
|
+
verify(p, 0, t1, v1)
|
238
|
+
verify(p, 8, t2, v2)
|
239
|
+
verify(p, 16, t3, v3)
|
240
240
|
end
|
241
241
|
end
|
242
242
|
end
|
data/spec/ffi/pointer_spec.rb
CHANGED
@@ -40,7 +40,7 @@ describe "Pointer" do
|
|
40
40
|
magic = 0x12345678
|
41
41
|
memory.put_int32(0, magic)
|
42
42
|
tp = ToPtrTest.new(memory)
|
43
|
-
PointerTestLib.ptr_ret_int32_t(tp, 0).should
|
43
|
+
PointerTestLib.ptr_ret_int32_t(tp, 0).should eq magic
|
44
44
|
end
|
45
45
|
class PointerDelegate < DelegateClass(FFI::Pointer)
|
46
46
|
def initialize(ptr)
|
@@ -55,7 +55,7 @@ describe "Pointer" do
|
|
55
55
|
magic = 0x12345678
|
56
56
|
memory.put_int32(0, magic)
|
57
57
|
ptr = PointerDelegate.new(memory)
|
58
|
-
PointerTestLib.ptr_ret_int32_t(ptr, 0).should
|
58
|
+
PointerTestLib.ptr_ret_int32_t(ptr, 0).should eq magic
|
59
59
|
end
|
60
60
|
it "Fixnum cannot be used as a Pointer argument" do
|
61
61
|
lambda { PointerTestLib.ptr_ret_int32(0, 0) }.should raise_error
|
@@ -69,13 +69,13 @@ describe "Pointer" do
|
|
69
69
|
it "#read_pointer" do
|
70
70
|
memory = FFI::MemoryPointer.new :pointer
|
71
71
|
PointerTestLib.ptr_set_pointer(memory, 0, PointerTestLib.ptr_from_address(0xdeadbeef))
|
72
|
-
memory.read_pointer.address.should
|
72
|
+
memory.read_pointer.address.should eq 0xdeadbeef
|
73
73
|
end
|
74
74
|
|
75
75
|
it "#write_pointer" do
|
76
76
|
memory = FFI::MemoryPointer.new :pointer
|
77
77
|
memory.write_pointer(PointerTestLib.ptr_from_address(0xdeadbeef))
|
78
|
-
PointerTestLib.ptr_ret_pointer(memory, 0).address.should
|
78
|
+
PointerTestLib.ptr_ret_pointer(memory, 0).address.should eq 0xdeadbeef
|
79
79
|
end
|
80
80
|
|
81
81
|
it "#read_array_of_pointer" do
|
@@ -86,7 +86,7 @@ describe "Pointer" do
|
|
86
86
|
end
|
87
87
|
array = memory.read_array_of_pointer(values.size)
|
88
88
|
values.each_with_index do |address, j|
|
89
|
-
array[j].address.should
|
89
|
+
array[j].address.should eq address
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -149,7 +149,7 @@ describe "AutoPointer" do
|
|
149
149
|
# note that if we called
|
150
150
|
# AutoPointerTestHelper.method(:release).to_proc inline, we'd
|
151
151
|
# have a reference to the pointer and it would never get GC'd.
|
152
|
-
|
152
|
+
AutoPointerSubclass.new(PointerTestLib.ptr_from_address(magic))
|
153
153
|
end
|
154
154
|
AutoPointerTestHelper.gc_everything loop_count
|
155
155
|
end
|
@@ -166,8 +166,8 @@ describe "AutoPointer" do
|
|
166
166
|
AutoPointerTestHelper.should_receive(:release).at_least(loop_count-wiggle_room).times
|
167
167
|
AutoPointerTestHelper.reset
|
168
168
|
loop_count.times do
|
169
|
-
|
170
|
-
|
169
|
+
FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
|
170
|
+
AutoPointerTestHelper.finalizer)
|
171
171
|
end
|
172
172
|
AutoPointerTestHelper.gc_everything loop_count
|
173
173
|
end
|
@@ -176,8 +176,8 @@ describe "AutoPointer" do
|
|
176
176
|
AutoPointerTestHelper.should_receive(:release).at_least(loop_count-wiggle_room).times
|
177
177
|
AutoPointerTestHelper.reset
|
178
178
|
loop_count.times do
|
179
|
-
|
180
|
-
|
179
|
+
FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
|
180
|
+
AutoPointerTestHelper.method(:release))
|
181
181
|
end
|
182
182
|
AutoPointerTestHelper.gc_everything loop_count
|
183
183
|
end
|
@@ -194,21 +194,18 @@ describe "AutoPointer" do
|
|
194
194
|
end
|
195
195
|
end.should_not raise_error
|
196
196
|
end
|
197
|
-
end
|
198
197
|
|
199
|
-
describe "
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
it "Buffer argument raises TypeError" do
|
210
|
-
lambda { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.should raise_error(::TypeError)
|
211
|
-
end
|
198
|
+
describe "#new" do
|
199
|
+
it "MemoryPointer argument raises TypeError" do
|
200
|
+
lambda { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.should raise_error(::TypeError)
|
201
|
+
end
|
202
|
+
it "AutoPointer argument raises TypeError" do
|
203
|
+
lambda { AutoPointerSubclass.new(AutoPointerSubclass.new(PointerTestLib.ptr_from_address(0))) }.should raise_error(::TypeError)
|
204
|
+
end
|
205
|
+
it "Buffer argument raises TypeError" do
|
206
|
+
lambda { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.should raise_error(::TypeError)
|
207
|
+
end
|
212
208
|
|
209
|
+
end
|
213
210
|
end
|
214
211
|
|
@@ -12,44 +12,44 @@ end
|
|
12
12
|
describe "MemoryPointer" do
|
13
13
|
it "makes a pointer from a string" do
|
14
14
|
m = FFI::MemoryPointer.from_string("FFI is Awesome")
|
15
|
-
m.total.should
|
16
|
-
m.type_size.should
|
15
|
+
m.total.should eq 15
|
16
|
+
m.type_size.should eq 1
|
17
17
|
end
|
18
18
|
|
19
19
|
it "makes a pointer from a string with multibyte characters" do
|
20
20
|
m = FFI::MemoryPointer.from_string("ぱんだ")
|
21
|
-
m.total.should
|
22
|
-
m.type_size.should
|
21
|
+
m.total.should eq 10
|
22
|
+
m.type_size.should eq 1
|
23
23
|
end
|
24
24
|
|
25
25
|
it "reads back a string" do
|
26
26
|
m = FFI::MemoryPointer.from_string("FFI is Awesome")
|
27
|
-
m.read_string.should
|
27
|
+
m.read_string.should eq "FFI is Awesome"
|
28
28
|
end
|
29
29
|
|
30
30
|
it "makes a pointer for a certain number of bytes" do
|
31
31
|
m = FFI::MemoryPointer.new(8)
|
32
32
|
m.write_array_of_int([1,2])
|
33
|
-
m.read_array_of_int(2).should
|
33
|
+
m.read_array_of_int(2).should eq [1,2]
|
34
34
|
end
|
35
35
|
|
36
36
|
it "allows access to an element of the pointer (as an array)" do
|
37
37
|
m = FFI::MemoryPointer.new(:int, 2)
|
38
38
|
m.write_array_of_int([1,2])
|
39
|
-
m[0].read_int.should
|
40
|
-
m[1].read_int.should
|
39
|
+
m[0].read_int.should eq 1
|
40
|
+
m[1].read_int.should eq 2
|
41
41
|
end
|
42
42
|
|
43
43
|
it "allows writing as an int" do
|
44
44
|
m = FFI::MemoryPointer.new(:int)
|
45
45
|
m.write_int(1)
|
46
|
-
m.read_int.should
|
46
|
+
m.read_int.should eq 1
|
47
47
|
end
|
48
48
|
|
49
49
|
it "allows writing as a long" do
|
50
50
|
m = FFI::MemoryPointer.new(:long)
|
51
51
|
m.write_long(10)
|
52
|
-
m.read_long.should
|
52
|
+
m.read_long.should eq 10
|
53
53
|
end
|
54
54
|
|
55
55
|
it "raises an error if you try putting a long into a pointer of size 1" do
|
@@ -72,40 +72,40 @@ describe "MemoryPointer" do
|
|
72
72
|
it "makes a pointer for a certain type" do
|
73
73
|
m = FFI::MemoryPointer.new(:int)
|
74
74
|
m.write_int(10)
|
75
|
-
m.read_int.should
|
75
|
+
m.read_int.should eq 10
|
76
76
|
end
|
77
77
|
|
78
78
|
it "makes a memory pointer for a number of a certain type" do
|
79
79
|
m = FFI::MemoryPointer.new(:int, 2)
|
80
80
|
m.write_array_of_int([1,2])
|
81
|
-
m.read_array_of_int(2).should
|
81
|
+
m.read_array_of_int(2).should eq [1,2]
|
82
82
|
end
|
83
83
|
|
84
84
|
it "makes a pointer for an object responding to #size" do
|
85
85
|
m = FFI::MemoryPointer.new(Struct.new(:size).new(8))
|
86
86
|
m.write_array_of_int([1,2])
|
87
|
-
m.read_array_of_int(2).should
|
87
|
+
m.read_array_of_int(2).should eq [1,2]
|
88
88
|
end
|
89
89
|
|
90
90
|
it "makes a pointer for a number of an object responding to #size" do
|
91
91
|
m = FFI::MemoryPointer.new(Struct.new(:size).new(4), 2)
|
92
92
|
m.write_array_of_int([1,2])
|
93
|
-
m.read_array_of_int(2).should
|
93
|
+
m.read_array_of_int(2).should eq [1,2]
|
94
94
|
end
|
95
95
|
it "MemoryPointer#address returns correct value" do
|
96
96
|
m = FFI::MemoryPointer.new(:long_long)
|
97
97
|
magic = 0x12345678
|
98
98
|
m.write_long(magic)
|
99
|
-
m.read_pointer.address.should
|
99
|
+
m.read_pointer.address.should eq magic
|
100
100
|
end
|
101
101
|
it "MemoryPointer#null? returns true for zero value" do
|
102
102
|
m = FFI::MemoryPointer.new(:long_long)
|
103
103
|
m.write_long(0)
|
104
|
-
m.read_pointer.null?.should
|
104
|
+
m.read_pointer.null?.should eq true
|
105
105
|
end
|
106
106
|
it "MemoryPointer#null? returns false for non-zero value" do
|
107
107
|
m = FFI::MemoryPointer.new(:long_long)
|
108
108
|
m.write_long(0x12345678)
|
109
|
-
m.read_pointer.null?.should
|
109
|
+
m.read_pointer.null?.should eq false
|
110
110
|
end
|
111
111
|
end
|