ffi 1.9.5-x86-mingw32 → 1.9.6-x86-mingw32
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 +15 -7
- data/Rakefile +13 -6
- data/ext/ffi_c/extconf.rb +2 -2
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/1.9/ffi_c.so +0 -0
- data/lib/2.0/ffi_c.so +0 -0
- data/lib/2.1/ffi_c.so +0 -0
- data/lib/ffi.rb +2 -0
- data/lib/ffi/version.rb +1 -1
- data/spec/ffi/async_callback_spec.rb +4 -5
- data/spec/ffi/bool_spec.rb +9 -8
- data/spec/ffi/buffer_spec.rb +64 -37
- data/spec/ffi/callback_spec.rb +195 -116
- data/spec/ffi/custom_param_type.rb +1 -1
- data/spec/ffi/custom_type_spec.rb +5 -6
- data/spec/ffi/dup_spec.rb +6 -8
- data/spec/ffi/enum_spec.rb +135 -129
- data/spec/ffi/errno_spec.rb +2 -2
- data/spec/ffi/ffi.log +5833 -0
- data/spec/ffi/ffi_spec.rb +4 -6
- data/spec/ffi/function_spec.rb +22 -11
- data/spec/ffi/io_spec.rb +0 -1
- data/spec/ffi/library_spec.rb +71 -36
- data/spec/ffi/long_double.rb +3 -4
- data/spec/ffi/managed_struct_spec.rb +14 -4
- data/spec/ffi/memorypointer_spec.rb +7 -1
- data/spec/ffi/number_spec.rb +43 -34
- data/spec/ffi/platform_spec.rb +76 -59
- data/spec/ffi/pointer_spec.rb +35 -31
- data/spec/ffi/rbx/attach_function_spec.rb +3 -4
- data/spec/ffi/rbx/memory_pointer_spec.rb +24 -22
- data/spec/ffi/rbx/spec_helper.rb +0 -1
- data/spec/ffi/rbx/struct_spec.rb +1 -2
- data/spec/ffi/spec_helper.rb +5 -2
- data/spec/ffi/string_spec.rb +22 -14
- data/spec/ffi/strptr_spec.rb +6 -7
- data/spec/ffi/struct_by_ref_spec.rb +4 -5
- data/spec/ffi/struct_by_ref_spec.rb.orig +43 -0
- data/spec/ffi/struct_callback_spec.rb +6 -7
- data/spec/ffi/struct_initialize_spec.rb +2 -3
- data/spec/ffi/struct_packed_spec.rb +12 -14
- data/spec/ffi/struct_spec.rb +203 -129
- data/spec/ffi/typedef_spec.rb +11 -10
- data/spec/ffi/union_spec.rb +8 -7
- data/spec/ffi/variadic_spec.rb +13 -10
- metadata +150 -139
@@ -4,11 +4,10 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe FFI::Struct, ' with inline callback functions' do
|
10
9
|
it 'should be able to define inline callback field' do
|
11
|
-
module CallbackMember1
|
10
|
+
expect(module CallbackMember1
|
12
11
|
extend FFI::Library
|
13
12
|
ffi_lib TestLibrary::PATH
|
14
13
|
DUMMY_CB = callback :dummy_cb, [ :int ], :int
|
@@ -20,8 +19,9 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
20
19
|
end
|
21
20
|
attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
|
22
21
|
attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
|
23
|
-
end.
|
22
|
+
end).to be_an_instance_of FFI::Function
|
24
23
|
end
|
24
|
+
|
25
25
|
it 'should take methods as callbacks' do
|
26
26
|
module CallbackMember2
|
27
27
|
extend FFI::Library
|
@@ -43,7 +43,7 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
43
43
|
ts = CallbackMember2::TestStruct.new
|
44
44
|
ts[:add] = StructCallbacks.method(:add)
|
45
45
|
|
46
|
-
CallbackMember2.struct_call_add_cb(ts, 1, 2).
|
46
|
+
expect(CallbackMember2.struct_call_add_cb(ts, 1, 2)).to eq(3)
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'should return callable object from []' do
|
@@ -63,8 +63,7 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
63
63
|
add = Proc.new { |a,b| a+b}
|
64
64
|
s[:add] = add
|
65
65
|
fn = s[:add]
|
66
|
-
fn.respond_to?(:call).
|
67
|
-
fn.call(1, 2).
|
66
|
+
expect(fn.respond_to?(:call)).to be true
|
67
|
+
expect(fn.call(1, 2)).to eq(3)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe FFI::Struct, ' with an initialize function' do
|
10
9
|
it "should call the initialize function" do
|
@@ -16,7 +15,7 @@ describe FFI::Struct, ' with an initialize function' do
|
|
16
15
|
self.magic = 42
|
17
16
|
end
|
18
17
|
end
|
19
|
-
StructWithInitialize.new.magic.
|
18
|
+
expect(StructWithInitialize.new.magic).to eq(42)
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
@@ -31,6 +30,6 @@ describe FFI::ManagedStruct, ' with an initialize function' do
|
|
31
30
|
end
|
32
31
|
def self.release;end
|
33
32
|
end
|
34
|
-
ManagedStructWithInitialize.new.magic.
|
33
|
+
expect(ManagedStructWithInitialize.new.magic).to eq(42)
|
35
34
|
end
|
36
35
|
end
|
@@ -4,49 +4,47 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe FFI::Struct do
|
10
9
|
it "packed :char followed by :int should have size of 5" do
|
11
|
-
Class.new(FFI::Struct) do
|
10
|
+
expect(Class.new(FFI::Struct) do
|
12
11
|
packed
|
13
12
|
layout :c, :char, :i, :int
|
14
|
-
end.size.
|
13
|
+
end.size).to eq(5)
|
15
14
|
end
|
16
15
|
|
17
16
|
it "packed :char followed by :int should have alignment of 1" do
|
18
|
-
Class.new(FFI::Struct) do
|
17
|
+
expect(Class.new(FFI::Struct) do
|
19
18
|
packed
|
20
19
|
layout :c, :char, :i, :int
|
21
|
-
end.alignment.
|
20
|
+
end.alignment).to eq(1)
|
22
21
|
end
|
23
22
|
|
24
23
|
it "packed(2) :char followed by :int should have size of 6" do
|
25
|
-
Class.new(FFI::Struct) do
|
24
|
+
expect(Class.new(FFI::Struct) do
|
26
25
|
packed 2
|
27
26
|
layout :c, :char, :i, :int
|
28
|
-
end.size.
|
27
|
+
end.size).to eq(6)
|
29
28
|
end
|
30
29
|
|
31
30
|
it "packed(2) :char followed by :int should have alignment of 2" do
|
32
|
-
Class.new(FFI::Struct) do
|
31
|
+
expect(Class.new(FFI::Struct) do
|
33
32
|
packed 2
|
34
33
|
layout :c, :char, :i, :int
|
35
|
-
end.alignment.
|
34
|
+
end.alignment).to eq(2)
|
36
35
|
end
|
37
36
|
|
38
37
|
it "packed :short followed by int should have size of 6" do
|
39
|
-
Class.new(FFI::Struct) do
|
38
|
+
expect(Class.new(FFI::Struct) do
|
40
39
|
packed
|
41
40
|
layout :s, :short, :i, :int
|
42
|
-
end.size.
|
41
|
+
end.size).to eq(6)
|
43
42
|
end
|
44
43
|
|
45
44
|
it "packed :short followed by int should have alignment of 1" do
|
46
|
-
Class.new(FFI::Struct) do
|
45
|
+
expect(Class.new(FFI::Struct) do
|
47
46
|
packed
|
48
47
|
layout :s, :short, :i, :int
|
49
|
-
end.alignment.
|
48
|
+
end.alignment).to eq(1)
|
50
49
|
end
|
51
|
-
|
52
50
|
end
|
data/spec/ffi/struct_spec.rb
CHANGED
@@ -4,7 +4,36 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
|
7
|
+
|
8
|
+
describe "Struct aligns fields correctly" do
|
9
|
+
it "char, followed by an int" do
|
10
|
+
class CIStruct < FFI::Struct
|
11
|
+
layout :c => :char, :i => :int
|
12
|
+
end
|
13
|
+
expect(CIStruct.size).to eq(8)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "short, followed by an int" do
|
17
|
+
class SIStruct < FFI::Struct
|
18
|
+
layout :s => :short, :i => :int
|
19
|
+
end
|
20
|
+
expect(SIStruct.size).to eq(8)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "int, followed by an int" do
|
24
|
+
class IIStruct < FFI::Struct
|
25
|
+
layout :i1 => :int, :i => :int
|
26
|
+
end
|
27
|
+
expect(IIStruct.size).to eq(8)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "long long, followed by an int" do
|
31
|
+
class LLIStruct < FFI::Struct
|
32
|
+
layout :l => :long_long, :i => :int
|
33
|
+
end
|
34
|
+
expect(LLIStruct.size).to eq(FFI::TYPE_UINT64.alignment == 4 ? 12 : 16)
|
35
|
+
end
|
36
|
+
end
|
8
37
|
|
9
38
|
describe "Struct tests" do
|
10
39
|
StructTypes = {
|
@@ -38,6 +67,7 @@ describe "Struct tests" do
|
|
38
67
|
class StringMember < FFI::Struct
|
39
68
|
layout :string, :string
|
40
69
|
end
|
70
|
+
|
41
71
|
it "Struct#[:pointer]" do
|
42
72
|
magic = 0x12345678
|
43
73
|
mp = FFI::MemoryPointer.new :long
|
@@ -45,8 +75,9 @@ describe "Struct tests" do
|
|
45
75
|
smp = FFI::MemoryPointer.new :pointer
|
46
76
|
smp.put_pointer(0, mp)
|
47
77
|
s = PointerMember.new smp
|
48
|
-
s[:pointer].
|
78
|
+
expect(s[:pointer]).to eq(mp)
|
49
79
|
end
|
80
|
+
|
50
81
|
it "Struct#[:pointer].nil? for NULL value" do
|
51
82
|
magic = 0x12345678
|
52
83
|
mp = FFI::MemoryPointer.new :long
|
@@ -54,8 +85,9 @@ describe "Struct tests" do
|
|
54
85
|
smp = FFI::MemoryPointer.new :pointer
|
55
86
|
smp.put_pointer(0, nil)
|
56
87
|
s = PointerMember.new smp
|
57
|
-
s[:pointer].null
|
88
|
+
expect(s[:pointer].null?).to be true
|
58
89
|
end
|
90
|
+
|
59
91
|
it "Struct#[:pointer]=" do
|
60
92
|
magic = 0x12345678
|
61
93
|
mp = FFI::MemoryPointer.new :long
|
@@ -63,19 +95,23 @@ describe "Struct tests" do
|
|
63
95
|
smp = FFI::MemoryPointer.new :pointer
|
64
96
|
s = PointerMember.new smp
|
65
97
|
s[:pointer] = mp
|
66
|
-
smp.get_pointer(0).
|
98
|
+
expect(smp.get_pointer(0)).to eq(mp)
|
67
99
|
end
|
100
|
+
|
68
101
|
it "Struct#[:pointer]=struct" do
|
69
102
|
smp = FFI::MemoryPointer.new :pointer
|
70
103
|
s = PointerMember.new smp
|
71
|
-
|
104
|
+
expect { s[:pointer] = s }.not_to raise_error Exception
|
105
|
+
expect { foo = s[:pointer] }.not_to raise_error Exception
|
72
106
|
end
|
107
|
+
|
73
108
|
it "Struct#[:pointer]=nil" do
|
74
109
|
smp = FFI::MemoryPointer.new :pointer
|
75
110
|
s = PointerMember.new smp
|
76
111
|
s[:pointer] = nil
|
77
|
-
smp.get_pointer(0).
|
112
|
+
expect(smp.get_pointer(0)).to be_null
|
78
113
|
end
|
114
|
+
|
79
115
|
it "Struct#[:string]" do
|
80
116
|
magic = "test"
|
81
117
|
mp = FFI::MemoryPointer.new 1024
|
@@ -83,64 +119,71 @@ describe "Struct tests" do
|
|
83
119
|
smp = FFI::MemoryPointer.new :pointer
|
84
120
|
smp.put_pointer(0, mp)
|
85
121
|
s = StringMember.new smp
|
86
|
-
s[:string].
|
122
|
+
expect(s[:string]).to eq(magic)
|
87
123
|
end
|
124
|
+
|
88
125
|
it "Struct#[:string].nil? for NULL value" do
|
89
126
|
smp = FFI::MemoryPointer.new :pointer
|
90
127
|
smp.put_pointer(0, nil)
|
91
128
|
s = StringMember.new smp
|
92
|
-
s[:string].
|
129
|
+
expect(s[:string]).to be_nil
|
93
130
|
end
|
131
|
+
|
94
132
|
it "Struct#layout works with :name, :type pairs" do
|
95
133
|
class PairLayout < FFI::Struct
|
96
134
|
layout :a, :int, :b, :long_long
|
97
135
|
end
|
98
136
|
ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
|
99
|
-
PairLayout.size.
|
137
|
+
expect(PairLayout.size).to eq((ll_off + 8))
|
100
138
|
mp = FFI::MemoryPointer.new(PairLayout.size)
|
101
139
|
s = PairLayout.new mp
|
102
140
|
s[:a] = 0x12345678
|
103
|
-
mp.get_int(0).
|
141
|
+
expect(mp.get_int(0)).to eq(0x12345678)
|
104
142
|
s[:b] = 0xfee1deadbeef
|
105
|
-
mp.get_int64(ll_off).
|
143
|
+
expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
|
106
144
|
end
|
145
|
+
|
107
146
|
it "Struct#layout works with :name, :type, offset tuples" do
|
108
147
|
class PairLayout < FFI::Struct
|
109
148
|
layout :a, :int, 0, :b, :long_long, 4
|
110
149
|
end
|
111
|
-
PairLayout.size.
|
150
|
+
expect(PairLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
|
112
151
|
mp = FFI::MemoryPointer.new(PairLayout.size)
|
113
152
|
s = PairLayout.new mp
|
114
153
|
s[:a] = 0x12345678
|
115
|
-
mp.get_int(0).
|
154
|
+
expect(mp.get_int(0)).to eq(0x12345678)
|
116
155
|
s[:b] = 0xfee1deadbeef
|
117
|
-
mp.get_int64(4).
|
156
|
+
expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
|
118
157
|
end
|
158
|
+
|
119
159
|
it "Struct#layout works with mixed :name,:type and :name,:type,offset" do
|
120
160
|
class MixedLayout < FFI::Struct
|
121
161
|
layout :a, :int, :b, :long_long, 4
|
122
162
|
end
|
123
|
-
MixedLayout.size.
|
163
|
+
expect(MixedLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
|
124
164
|
mp = FFI::MemoryPointer.new(MixedLayout.size)
|
125
165
|
s = MixedLayout.new mp
|
126
166
|
s[:a] = 0x12345678
|
127
|
-
mp.get_int(0).
|
167
|
+
expect(mp.get_int(0)).to eq(0x12345678)
|
128
168
|
s[:b] = 0xfee1deadbeef
|
129
|
-
mp.get_int64(4).
|
169
|
+
expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
|
130
170
|
end
|
131
171
|
|
132
|
-
|
133
|
-
|
134
|
-
|
172
|
+
rb_maj, rb_min = RUBY_VERSION.split('.')
|
173
|
+
if rb_maj.to_i >= 1 && rb_min.to_i >= 9 || RUBY_PLATFORM =~ /java/
|
174
|
+
it "Struct#layout withs with a hash of :name => type" do
|
175
|
+
class HashLayout < FFI::Struct
|
176
|
+
layout :a => :int, :b => :long_long
|
177
|
+
end
|
178
|
+
ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
|
179
|
+
expect(HashLayout.size).to eq(ll_off + 8)
|
180
|
+
mp = FFI::MemoryPointer.new(HashLayout.size)
|
181
|
+
s = HashLayout.new mp
|
182
|
+
s[:a] = 0x12345678
|
183
|
+
expect(mp.get_int(0)).to eq(0x12345678)
|
184
|
+
s[:b] = 0xfee1deadbeef
|
185
|
+
expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
|
135
186
|
end
|
136
|
-
ll_off = (FFI::TYPE_UINT64.alignment == 4? 4 : 8)
|
137
|
-
HashLayout.size.should == (ll_off + 8)
|
138
|
-
mp = FFI::MemoryPointer.new(HashLayout.size)
|
139
|
-
s = HashLayout.new mp
|
140
|
-
s[:a] = 0x12345678
|
141
|
-
mp.get_int(0).should == 0x12345678
|
142
|
-
s[:b] = 0xfee1deadbeef
|
143
|
-
mp.get_int64(ll_off).should == 0xfee1deadbeef
|
144
187
|
end
|
145
188
|
|
146
189
|
it "subclass overrides initialize without calling super" do
|
@@ -156,104 +199,115 @@ describe "Struct tests" do
|
|
156
199
|
|
157
200
|
end
|
158
201
|
s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
|
159
|
-
s[:a].
|
160
|
-
s[:b].
|
202
|
+
expect(s[:a]).to eq(0x1eefbeef)
|
203
|
+
expect(s[:b]).to eq(0xdeadcafebabe)
|
161
204
|
end
|
162
205
|
|
163
206
|
it "Can use Struct subclass as parameter type" do
|
164
|
-
module StructParam
|
207
|
+
expect(module StructParam
|
165
208
|
extend FFI::Library
|
166
209
|
ffi_lib TestLibrary::PATH
|
167
210
|
class TestStruct < FFI::Struct
|
168
211
|
layout :c, :char
|
169
212
|
end
|
170
213
|
attach_function :struct_field_s8, [ TestStruct.in ], :char
|
171
|
-
end.
|
214
|
+
end).to be_an_instance_of FFI::Function
|
172
215
|
end
|
216
|
+
|
173
217
|
it "Can use Struct subclass as IN parameter type" do
|
174
|
-
module StructParam2
|
218
|
+
expect(module StructParam2
|
175
219
|
extend FFI::Library
|
176
220
|
ffi_lib TestLibrary::PATH
|
177
221
|
class TestStruct < FFI::Struct
|
178
222
|
layout :c, :char
|
179
223
|
end
|
180
224
|
attach_function :struct_field_s8, [ TestStruct.in ], :char
|
181
|
-
end.
|
225
|
+
end).to be_an_instance_of FFI::Function
|
182
226
|
end
|
227
|
+
|
183
228
|
it "Can use Struct subclass as OUT parameter type" do
|
184
|
-
module StructParam3
|
229
|
+
expect(module StructParam3
|
185
230
|
extend FFI::Library
|
186
231
|
ffi_lib TestLibrary::PATH
|
187
232
|
class TestStruct < FFI::Struct
|
188
233
|
layout :c, :char
|
189
234
|
end
|
190
235
|
attach_function :struct_field_s8, [ TestStruct.out ], :char
|
191
|
-
end.
|
236
|
+
end).to be_an_instance_of FFI::Function
|
192
237
|
end
|
238
|
+
|
193
239
|
it "can be passed directly as a :pointer parameter" do
|
194
240
|
class TestStruct < FFI::Struct
|
195
241
|
layout :i, :int
|
196
242
|
end
|
197
243
|
s = TestStruct.new
|
198
244
|
s[:i] = 0x12
|
199
|
-
LibTest.ptr_ret_int32_t(s, 0).
|
245
|
+
expect(LibTest.ptr_ret_int32_t(s, 0)).to eq(0x12)
|
200
246
|
end
|
247
|
+
|
201
248
|
it ":char member aligned correctly" do
|
202
249
|
class AlignChar < FFI::Struct
|
203
250
|
layout :c, :char, :v, :char
|
204
251
|
end
|
205
252
|
s = AlignChar.new
|
206
253
|
s[:v] = 0x12
|
207
|
-
LibTest.struct_align_s8(s.pointer).
|
254
|
+
expect(LibTest.struct_align_s8(s.pointer)).to eq(0x12)
|
208
255
|
end
|
256
|
+
|
209
257
|
it ":short member aligned correctly" do
|
210
258
|
class AlignShort < FFI::Struct
|
211
259
|
layout :c, :char, :v, :short
|
212
260
|
end
|
213
261
|
s = AlignShort.alloc_in
|
214
262
|
s[:v] = 0x1234
|
215
|
-
LibTest.struct_align_s16(s.pointer).
|
263
|
+
expect(LibTest.struct_align_s16(s.pointer)).to eq(0x1234)
|
216
264
|
end
|
265
|
+
|
217
266
|
it ":int member aligned correctly" do
|
218
267
|
class AlignInt < FFI::Struct
|
219
268
|
layout :c, :char, :v, :int
|
220
269
|
end
|
221
270
|
s = AlignInt.alloc_in
|
222
271
|
s[:v] = 0x12345678
|
223
|
-
LibTest.struct_align_s32(s.pointer).
|
272
|
+
expect(LibTest.struct_align_s32(s.pointer)).to eq(0x12345678)
|
224
273
|
end
|
274
|
+
|
225
275
|
it ":long_long member aligned correctly" do
|
226
276
|
class AlignLongLong < FFI::Struct
|
227
277
|
layout :c, :char, :v, :long_long
|
228
278
|
end
|
229
279
|
s = AlignLongLong.alloc_in
|
230
280
|
s[:v] = 0x123456789abcdef0
|
231
|
-
LibTest.struct_align_s64(s.pointer).
|
281
|
+
expect(LibTest.struct_align_s64(s.pointer)).to eq(0x123456789abcdef0)
|
232
282
|
end
|
283
|
+
|
233
284
|
it ":long member aligned correctly" do
|
234
285
|
class AlignLong < FFI::Struct
|
235
286
|
layout :c, :char, :v, :long
|
236
287
|
end
|
237
288
|
s = AlignLong.alloc_in
|
238
289
|
s[:v] = 0x12345678
|
239
|
-
LibTest.struct_align_long(s.pointer).
|
290
|
+
expect(LibTest.struct_align_long(s.pointer)).to eq(0x12345678)
|
240
291
|
end
|
292
|
+
|
241
293
|
it ":float member aligned correctly" do
|
242
294
|
class AlignFloat < FFI::Struct
|
243
295
|
layout :c, :char, :v, :float
|
244
296
|
end
|
245
297
|
s = AlignFloat.alloc_in
|
246
298
|
s[:v] = 1.23456
|
247
|
-
(LibTest.struct_align_f32(s.pointer) - 1.23456).abs.
|
299
|
+
expect((LibTest.struct_align_f32(s.pointer) - 1.23456).abs).to be < 0.00001
|
248
300
|
end
|
301
|
+
|
249
302
|
it ":double member aligned correctly" do
|
250
303
|
class AlignDouble < FFI::Struct
|
251
304
|
layout :c, :char, :v, :double
|
252
305
|
end
|
253
306
|
s = AlignDouble.alloc_in
|
254
307
|
s[:v] = 1.23456789
|
255
|
-
(LibTest.struct_align_f64(s.pointer) - 1.23456789).abs.
|
308
|
+
expect((LibTest.struct_align_f64(s.pointer) - 1.23456789).abs).to be < 0.00000001
|
256
309
|
end
|
310
|
+
|
257
311
|
it ":ulong, :pointer struct" do
|
258
312
|
class ULPStruct < FFI::Struct
|
259
313
|
layout :ul, :ulong, :p, :pointer
|
@@ -261,7 +315,7 @@ describe "Struct tests" do
|
|
261
315
|
s = ULPStruct.alloc_in
|
262
316
|
s[:ul] = 0xdeadbeef
|
263
317
|
s[:p] = LibTest.ptr_from_address(0x12345678)
|
264
|
-
s.pointer.get_ulong(0).
|
318
|
+
expect(s.pointer.get_ulong(0)).to eq(0xdeadbeef)
|
265
319
|
end
|
266
320
|
def test_num_field(type, v)
|
267
321
|
klass = Class.new(FFI::Struct)
|
@@ -269,9 +323,9 @@ describe "Struct tests" do
|
|
269
323
|
|
270
324
|
s = klass.new
|
271
325
|
s[:v] = v
|
272
|
-
s.pointer.send("get_#{type.to_s}", 0).
|
326
|
+
expect(s.pointer.send("get_#{type.to_s}", 0)).to eq(v)
|
273
327
|
s.pointer.send("put_#{type.to_s}", 0, 0)
|
274
|
-
s[:v].
|
328
|
+
expect(s[:v]).to eq(0)
|
275
329
|
end
|
276
330
|
def self.int_field_test(type, values)
|
277
331
|
values.each do |v|
|
@@ -295,6 +349,7 @@ describe "Struct tests" do
|
|
295
349
|
int_field_test(:long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
|
296
350
|
int_field_test(:ulong, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
|
297
351
|
end
|
352
|
+
|
298
353
|
it ":float field r/w" do
|
299
354
|
klass = Class.new(FFI::Struct)
|
300
355
|
klass.layout :v, :float, :dummy, :long
|
@@ -302,8 +357,9 @@ describe "Struct tests" do
|
|
302
357
|
s = klass.new
|
303
358
|
value = 1.23456
|
304
359
|
s[:v] = value
|
305
|
-
(s.pointer.get_float(0) - value).abs.
|
360
|
+
expect((s.pointer.get_float(0) - value).abs).to be < 0.0001
|
306
361
|
end
|
362
|
+
|
307
363
|
it ":double field r/w" do
|
308
364
|
klass = Class.new(FFI::Struct)
|
309
365
|
klass.layout :v, :double, :dummy, :long
|
@@ -311,7 +367,7 @@ describe "Struct tests" do
|
|
311
367
|
s = klass.new
|
312
368
|
value = 1.23456
|
313
369
|
s[:v] = value
|
314
|
-
(s.pointer.get_double(0) - value).abs.
|
370
|
+
expect((s.pointer.get_double(0) - value).abs).to be < 0.0001
|
315
371
|
end
|
316
372
|
module EnumFields
|
317
373
|
extend FFI::Library
|
@@ -326,8 +382,8 @@ describe "Struct tests" do
|
|
326
382
|
s = EnumFields::TestStruct.new
|
327
383
|
s[:c] = :c3
|
328
384
|
|
329
|
-
s.pointer.get_uint(FFI::Type::INT32.size).
|
330
|
-
s[:c].
|
385
|
+
expect(s.pointer.get_uint(FFI::Type::INT32.size)).to eq(30)
|
386
|
+
expect(s[:c]).to eq(:c3)
|
331
387
|
end
|
332
388
|
|
333
389
|
it "array of :enum field" do
|
@@ -337,11 +393,11 @@ describe "Struct tests" do
|
|
337
393
|
end
|
338
394
|
|
339
395
|
EnumFields::TestEnum.symbols.each_with_index do |val, i|
|
340
|
-
s.pointer.get_uint(FFI::Type::INT32.size * (2 + i)).
|
396
|
+
expect(s.pointer.get_uint(FFI::Type::INT32.size * (2 + i))).to eq(EnumFields::TestEnum[val])
|
341
397
|
end
|
342
398
|
|
343
399
|
s[:d].each_with_index do |val, i|
|
344
|
-
val.
|
400
|
+
expect(val).to eq(EnumFields::TestEnum.symbols[i])
|
345
401
|
end
|
346
402
|
end
|
347
403
|
|
@@ -357,47 +413,52 @@ describe "Struct tests" do
|
|
357
413
|
attach_function :struct_call_add_cb, [TestStruct.in, :int, :int], :int
|
358
414
|
attach_function :struct_call_sub_cb, [TestStruct.in, :int, :int], :int
|
359
415
|
end
|
416
|
+
|
360
417
|
it "Can have CallbackInfo struct field" do
|
361
418
|
s = CallbackMember::TestStruct.new
|
362
419
|
add_proc = lambda { |a, b| a+b }
|
363
420
|
sub_proc = lambda { |a, b| a-b }
|
364
421
|
s[:add] = add_proc
|
365
422
|
s[:sub] = sub_proc
|
366
|
-
CallbackMember.struct_call_add_cb(s, 40, 2).
|
367
|
-
CallbackMember.struct_call_sub_cb(s, 44, 2).
|
423
|
+
expect(CallbackMember.struct_call_add_cb(s, 40, 2)).to eq(42)
|
424
|
+
expect(CallbackMember.struct_call_sub_cb(s, 44, 2)).to eq(42)
|
368
425
|
end
|
426
|
+
|
369
427
|
it "Can return its members as a list" do
|
370
428
|
class TestStruct < FFI::Struct
|
371
429
|
layout :a, :int, :b, :int, :c, :int
|
372
430
|
end
|
373
|
-
TestStruct.members.
|
431
|
+
expect(TestStruct.members).to include(:a, :b, :c)
|
374
432
|
end
|
433
|
+
|
375
434
|
it "Can return its instance members and values as lists" do
|
376
435
|
class TestStruct < FFI::Struct
|
377
436
|
layout :a, :int, :b, :int, :c, :int
|
378
437
|
end
|
379
438
|
s = TestStruct.new
|
380
|
-
s.members.
|
439
|
+
expect(s.members).to include(:a, :b, :c)
|
381
440
|
s[:a] = 1
|
382
441
|
s[:b] = 2
|
383
442
|
s[:c] = 3
|
384
|
-
s.values.
|
443
|
+
expect(s.values).to include(1, 2, 3)
|
385
444
|
end
|
445
|
+
|
386
446
|
it 'should return an ordered field/offset pairs array' do
|
387
447
|
class TestStruct < FFI::Struct
|
388
448
|
layout :a, :int, :b, :int, :c, :int
|
389
449
|
end
|
390
450
|
s = TestStruct.new
|
391
|
-
s.offsets.
|
392
|
-
TestStruct.offsets.
|
451
|
+
expect(s.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
|
452
|
+
expect(TestStruct.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
|
393
453
|
end
|
454
|
+
|
394
455
|
it "Struct#offset_of returns offset of field within struct" do
|
395
456
|
class TestStruct < FFI::Struct
|
396
457
|
layout :a, :int, :b, :int, :c, :int
|
397
458
|
end
|
398
|
-
TestStruct.offset_of(:a).
|
399
|
-
TestStruct.offset_of(:b).
|
400
|
-
TestStruct.offset_of(:c).
|
459
|
+
expect(TestStruct.offset_of(:a)).to eq(0)
|
460
|
+
expect(TestStruct.offset_of(:b)).to eq(4)
|
461
|
+
expect(TestStruct.offset_of(:c)).to eq(8)
|
401
462
|
end
|
402
463
|
end
|
403
464
|
|
@@ -422,7 +483,7 @@ describe FFI::Struct, ".layout" do
|
|
422
483
|
|
423
484
|
instance = klass.new
|
424
485
|
instance[:number] = 0xA1
|
425
|
-
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).
|
486
|
+
expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
|
426
487
|
end
|
427
488
|
end
|
428
489
|
|
@@ -434,7 +495,7 @@ describe FFI::Struct, ".layout" do
|
|
434
495
|
|
435
496
|
instance = FFISpecs::TestStruct.new
|
436
497
|
instance[:number] = 0xA1
|
437
|
-
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).
|
498
|
+
expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
|
438
499
|
end
|
439
500
|
|
440
501
|
it "resolves a type from the enclosing module" do
|
@@ -448,7 +509,7 @@ describe FFI::Struct, ".layout" do
|
|
448
509
|
|
449
510
|
instance = FFISpecs::LibTest::TestStruct.new
|
450
511
|
instance[:number] = 0xA1
|
451
|
-
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).
|
512
|
+
expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
|
452
513
|
end
|
453
514
|
end
|
454
515
|
end
|
@@ -469,24 +530,29 @@ describe FFI::Struct, ' with a nested struct field' do
|
|
469
530
|
before do
|
470
531
|
@cs = LibTest::ContainerStruct.new
|
471
532
|
end
|
533
|
+
|
472
534
|
it 'should align correctly nested struct field' do
|
473
535
|
@cs[:ns][:i] = 123
|
474
|
-
LibTest.struct_align_nested_struct(@cs.to_ptr).
|
536
|
+
expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
|
475
537
|
end
|
538
|
+
|
476
539
|
it 'should correctly calculate Container size (in bytes)' do
|
477
|
-
LibTest::ContainerStruct.size.
|
540
|
+
expect(LibTest::ContainerStruct.size).to eq(8)
|
478
541
|
end
|
542
|
+
|
479
543
|
it 'should return a Struct object when the field is accessed' do
|
480
|
-
@cs[:ns].is_a?(FFI::Struct).
|
544
|
+
expect(@cs[:ns].is_a?(FFI::Struct)).to be true
|
481
545
|
end
|
546
|
+
|
482
547
|
it 'should read a value from memory' do
|
483
548
|
@cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
|
484
|
-
@cs[:ns][:i].
|
549
|
+
expect(@cs[:ns][:i]).to eq(123)
|
485
550
|
end
|
551
|
+
|
486
552
|
it 'should write a value to memory' do
|
487
553
|
@cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
|
488
554
|
@cs[:ns][:i] = 456
|
489
|
-
LibTest.struct_align_nested_struct(@cs.to_ptr).
|
555
|
+
expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
|
490
556
|
end
|
491
557
|
|
492
558
|
it 'should be able to assign struct instance to nested field' do
|
@@ -494,8 +560,8 @@ describe FFI::Struct, ' with a nested struct field' do
|
|
494
560
|
ns = LibTest::NestedStruct.new
|
495
561
|
ns[:i] = 567
|
496
562
|
cs[:ns] = ns
|
497
|
-
cs[:ns][:i].
|
498
|
-
LibTest.struct_align_nested_struct(cs.to_ptr).
|
563
|
+
expect(cs[:ns][:i]).to eq(567)
|
564
|
+
expect(LibTest.struct_align_nested_struct(cs.to_ptr)).to eq(567)
|
499
565
|
end
|
500
566
|
end
|
501
567
|
|
@@ -519,33 +585,33 @@ describe FFI::Struct, ' with a nested array of structs' do
|
|
519
585
|
|
520
586
|
it 'should align correctly nested struct field' do
|
521
587
|
@cs[:ns][0][:i] = 123
|
522
|
-
InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr).
|
588
|
+
expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
|
523
589
|
end
|
524
590
|
|
525
591
|
it 'should correctly calculate Container size (in bytes)' do
|
526
|
-
InlineArrayOfStructs::ContainerStruct.size.
|
592
|
+
expect(InlineArrayOfStructs::ContainerStruct.size).to eq(8)
|
527
593
|
end
|
528
594
|
|
529
595
|
it 'should return a Struct object when the field is accessed' do
|
530
|
-
@cs[:ns][0].is_a?(FFI::Struct).
|
596
|
+
expect(@cs[:ns][0].is_a?(FFI::Struct)).to be true
|
531
597
|
end
|
532
598
|
|
533
599
|
it 'should read a value from memory' do
|
534
600
|
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
535
|
-
@cs[:ns][0][:i].
|
601
|
+
expect(@cs[:ns][0][:i]).to eq(123)
|
536
602
|
end
|
537
603
|
|
538
604
|
it 'should write a value to memory' do
|
539
605
|
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
540
606
|
@cs[:ns][0][:i] = 456
|
541
|
-
InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr).
|
607
|
+
expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
|
542
608
|
end
|
543
609
|
|
544
610
|
it 'should support Enumerable#each' do
|
545
611
|
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
546
612
|
ints = []
|
547
613
|
@cs[:ns].each { |s| ints << s[:i] }
|
548
|
-
ints[0].
|
614
|
+
expect(ints[0]).to eq(123)
|
549
615
|
end
|
550
616
|
end
|
551
617
|
|
@@ -575,22 +641,22 @@ describe FFI::Struct, ' by value' do
|
|
575
641
|
|
576
642
|
it 'return using pre-set values' do
|
577
643
|
s = LibTest.struct_return_s8s32
|
578
|
-
s[:s8].
|
579
|
-
s[:s32].
|
644
|
+
expect(s[:s8]).to eq(0x7f)
|
645
|
+
expect(s[:s32]).to eq(0x12345678)
|
580
646
|
end
|
581
647
|
|
582
648
|
it 'return using passed in values' do
|
583
649
|
s = LibTest.struct_s8s32_set(123, 456789)
|
584
|
-
s[:s8].
|
585
|
-
s[:s32].
|
650
|
+
expect(s[:s8]).to eq(123)
|
651
|
+
expect(s[:s32]).to eq(456789)
|
586
652
|
end
|
587
653
|
|
588
654
|
it 'parameter' do
|
589
655
|
s = LibTest::S8S32.new
|
590
656
|
s[:s8] = 0x12
|
591
657
|
s[:s32] = 0x34567890
|
592
|
-
LibTest.struct_s8s32_get_s8(s).
|
593
|
-
LibTest.struct_s8s32_get_s32(s).
|
658
|
+
expect(LibTest.struct_s8s32_get_s8(s)).to eq(0x12)
|
659
|
+
expect(LibTest.struct_s8s32_get_s32(s)).to eq(0x34567890)
|
594
660
|
end
|
595
661
|
|
596
662
|
it 'parameter with following s32' do
|
@@ -598,7 +664,7 @@ describe FFI::Struct, ' by value' do
|
|
598
664
|
s[:s8] = 0x12
|
599
665
|
s[:s32] = 0x34567890
|
600
666
|
|
601
|
-
LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead).
|
667
|
+
expect(LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead)).to eq(0x1eefdead)
|
602
668
|
end
|
603
669
|
|
604
670
|
# it 'parameter with following s64' do
|
@@ -615,9 +681,9 @@ describe FFI::Struct, ' by value' do
|
|
615
681
|
s[:s8] = 0x12
|
616
682
|
s[:s32] = 0x34567890
|
617
683
|
out = LibTest::S8S32.new
|
618
|
-
LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s).
|
619
|
-
out[:s8].
|
620
|
-
out[:s32].
|
684
|
+
expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
|
685
|
+
expect(out[:s8]).to eq(s[:s8])
|
686
|
+
expect(out[:s32]).to eq(s[:s32])
|
621
687
|
end
|
622
688
|
|
623
689
|
it 'parameter with preceding s32,string,s32' do
|
@@ -625,7 +691,7 @@ describe FFI::Struct, ' by value' do
|
|
625
691
|
s[:s8] = 0x12
|
626
692
|
s[:s32] = 0x34567890
|
627
693
|
out = 0.chr * 32
|
628
|
-
LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s).
|
694
|
+
expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
|
629
695
|
end
|
630
696
|
|
631
697
|
it 'parameter, returning struct by value' do
|
@@ -634,15 +700,15 @@ describe FFI::Struct, ' by value' do
|
|
634
700
|
s[:s32] = 0x34567890
|
635
701
|
|
636
702
|
ret = LibTest.struct_s8s32_ret_s8s32(s)
|
637
|
-
ret[:s8].
|
638
|
-
ret[:s32].
|
703
|
+
expect(ret[:s8]).to eq(s[:s8])
|
704
|
+
expect(ret[:s32]).to eq(s[:s32])
|
639
705
|
end
|
640
706
|
|
641
707
|
it 'varargs returning a struct' do
|
642
708
|
string = "test"
|
643
709
|
s = LibTest.struct_varargs_ret_struct_string(4, :string, string)
|
644
|
-
s[:len].
|
645
|
-
s[:bytes].
|
710
|
+
expect(s[:len]).to eq(string.length)
|
711
|
+
expect(s[:bytes]).to eq(string)
|
646
712
|
end
|
647
713
|
end
|
648
714
|
|
@@ -659,27 +725,32 @@ describe FFI::Struct, ' with an array field' do
|
|
659
725
|
before do
|
660
726
|
@s = LibTest::StructWithArray.new
|
661
727
|
end
|
728
|
+
|
662
729
|
it 'should correctly calculate StructWithArray size (in bytes)' do
|
663
|
-
LibTest::StructWithArray.size.
|
730
|
+
expect(LibTest::StructWithArray.size).to eq(24)
|
664
731
|
end
|
732
|
+
|
665
733
|
it 'should read values from memory' do
|
666
734
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
667
|
-
@s[:a].to_a.
|
735
|
+
expect(@s[:a].to_a).to eq([0, 1, 2, 3, 4])
|
668
736
|
end
|
669
737
|
# it 'should cache array object for successive calls' do
|
670
738
|
# @s[:a].object_id.should == @s[:a].object_id
|
671
739
|
# end
|
740
|
+
|
672
741
|
it 'should return the number of elements in the array field' do
|
673
742
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
674
|
-
@s[:a].size.
|
743
|
+
expect(@s[:a].size).to eq(5)
|
675
744
|
end
|
745
|
+
|
676
746
|
it 'should allow iteration through the array elements' do
|
677
747
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
678
|
-
@s[:a].each_with_index { |elem, i| elem.
|
748
|
+
@s[:a].each_with_index { |elem, i| expect(elem).to eq(i) }
|
679
749
|
end
|
750
|
+
|
680
751
|
it 'should return the pointer to the array' do
|
681
752
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
682
|
-
@s[:a].to_ptr.
|
753
|
+
expect(@s[:a].to_ptr).to eq(LibTest::struct_field_array(@s.to_ptr))
|
683
754
|
end
|
684
755
|
end
|
685
756
|
|
@@ -698,22 +769,25 @@ describe 'BuggedStruct' do
|
|
698
769
|
end
|
699
770
|
attach_function :bugged_struct_size, [], :uint
|
700
771
|
end
|
772
|
+
|
701
773
|
it 'should return its correct size' do
|
702
|
-
LibTest::BuggedStruct.size.
|
774
|
+
expect(LibTest::BuggedStruct.size).to eq(LibTest.bugged_struct_size)
|
703
775
|
end
|
776
|
+
|
704
777
|
it "offsets within struct should be correct" do
|
705
|
-
LibTest::BuggedStruct.offset_of(:visible).
|
706
|
-
LibTest::BuggedStruct.offset_of(:x).
|
707
|
-
LibTest::BuggedStruct.offset_of(:y).
|
708
|
-
LibTest::BuggedStruct.offset_of(:rx).
|
709
|
-
LibTest::BuggedStruct.offset_of(:ry).
|
710
|
-
LibTest::BuggedStruct.offset_of(:order).
|
711
|
-
LibTest::BuggedStruct.offset_of(:size).
|
778
|
+
expect(LibTest::BuggedStruct.offset_of(:visible)).to eq(0)
|
779
|
+
expect(LibTest::BuggedStruct.offset_of(:x)).to eq(4)
|
780
|
+
expect(LibTest::BuggedStruct.offset_of(:y)).to eq(8)
|
781
|
+
expect(LibTest::BuggedStruct.offset_of(:rx)).to eq(12)
|
782
|
+
expect(LibTest::BuggedStruct.offset_of(:ry)).to eq(14)
|
783
|
+
expect(LibTest::BuggedStruct.offset_of(:order)).to eq(16)
|
784
|
+
expect(LibTest::BuggedStruct.offset_of(:size)).to eq(17)
|
712
785
|
end
|
786
|
+
|
713
787
|
it 'should return correct field/offset pairs' do
|
714
|
-
LibTest::BuggedStruct.offsets.sort do |a, b|
|
788
|
+
expect(LibTest::BuggedStruct.offsets.sort do |a, b|
|
715
789
|
a[1] <=> b[1]
|
716
|
-
end.
|
790
|
+
end).to eq([[:visible, 0], [:x, 4], [:y, 8], [:rx, 12], [:ry, 14], [:order, 16], [:size, 17]])
|
717
791
|
end
|
718
792
|
end
|
719
793
|
|
@@ -723,11 +797,11 @@ describe "Struct allocation" do
|
|
723
797
|
layout :i, :uint
|
724
798
|
end
|
725
799
|
p = FFI::MemoryPointer.new(S, 2)
|
726
|
-
p.total.
|
727
|
-
p.type_size.
|
800
|
+
expect(p.total).to eq(8)
|
801
|
+
expect(p.type_size).to eq(4)
|
728
802
|
p.put_uint(4, 0xdeadbeef)
|
729
|
-
S.new(p[1])[:i].
|
730
|
-
p[1].address.
|
803
|
+
expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
|
804
|
+
expect(p[1].address).to eq((p[0].address + 4))
|
731
805
|
end
|
732
806
|
|
733
807
|
it "Buffer.new(Struct, 2)" do
|
@@ -735,53 +809,53 @@ describe "Struct allocation" do
|
|
735
809
|
layout :i, :uint
|
736
810
|
end
|
737
811
|
p = FFI::Buffer.new(S, 2)
|
738
|
-
p.total.
|
739
|
-
p.type_size.
|
812
|
+
expect(p.total).to eq(8)
|
813
|
+
expect(p.type_size).to eq(4)
|
740
814
|
p.put_uint(4, 0xdeadbeef)
|
741
|
-
S.new(p[1])[:i].
|
815
|
+
expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
|
742
816
|
end
|
743
817
|
|
744
818
|
it "null? should be true when initialized with NULL pointer" do
|
745
819
|
class S < FFI::Struct
|
746
820
|
layout :i, :uint
|
747
821
|
end
|
748
|
-
S.new(FFI::Pointer::NULL).
|
822
|
+
expect(S.new(FFI::Pointer::NULL)).to be_null
|
749
823
|
end
|
750
824
|
|
751
825
|
it "null? should be false when initialized with non-NULL pointer" do
|
752
826
|
class S < FFI::Struct
|
753
827
|
layout :i, :uint
|
754
828
|
end
|
755
|
-
S.new(FFI::MemoryPointer.new(S)).
|
829
|
+
expect(S.new(FFI::MemoryPointer.new(S))).not_to be_null
|
756
830
|
end
|
757
831
|
|
758
832
|
it "supports :bool as a struct member" do
|
759
|
-
|
833
|
+
expect do
|
760
834
|
c = Class.new(FFI::Struct) do
|
761
835
|
layout :b, :bool
|
762
836
|
end
|
763
837
|
struct = c.new
|
764
838
|
struct[:b] = ! struct[:b]
|
765
|
-
end.
|
839
|
+
end.not_to raise_error Exception
|
766
840
|
end
|
767
841
|
|
768
842
|
end
|
769
843
|
|
770
844
|
describe "variable-length arrays" do
|
771
845
|
it "zero length array should be accepted as last field" do
|
772
|
-
|
846
|
+
expect {
|
773
847
|
Class.new(FFI::Struct) do
|
774
848
|
layout :count, :int, :data, [ :char, 0 ]
|
775
849
|
end
|
776
|
-
}.
|
850
|
+
}.not_to raise_error Exception
|
777
851
|
end
|
778
852
|
|
779
853
|
it "zero length array before last element should raise error" do
|
780
|
-
|
854
|
+
expect {
|
781
855
|
Class.new(FFI::Struct) do
|
782
856
|
layout :data, [ :char, 0 ], :count, :int
|
783
857
|
end
|
784
|
-
}.
|
858
|
+
}.to raise_error
|
785
859
|
end
|
786
860
|
|
787
861
|
it "can access elements of array" do
|
@@ -791,8 +865,8 @@ describe "variable-length arrays" do
|
|
791
865
|
s = struct_class.new(FFI::MemoryPointer.new(1024))
|
792
866
|
s[:data][0] = 0x1eadbeef
|
793
867
|
s[:data][1] = 0x12345678
|
794
|
-
s[:data][0].
|
795
|
-
s[:data][1].
|
868
|
+
expect(s[:data][0]).to eq(0x1eadbeef)
|
869
|
+
expect(s[:data][1]).to eq(0x12345678)
|
796
870
|
end
|
797
871
|
|
798
872
|
it "non-variable length array is bounds checked" do
|
@@ -801,8 +875,8 @@ describe "variable-length arrays" do
|
|
801
875
|
end
|
802
876
|
s = struct_class.new(FFI::MemoryPointer.new(1024))
|
803
877
|
s[:data][0] = 0x1eadbeef
|
804
|
-
|
805
|
-
s[:data][0].
|
806
|
-
|
878
|
+
expect { s[:data][1] = 0x12345678 }.to raise_error
|
879
|
+
expect(s[:data][0]).to eq(0x1eadbeef)
|
880
|
+
expect { expect(s[:data][1]).to == 0x12345678 }.to raise_error
|
807
881
|
end
|
808
882
|
end
|