ffi-struct_ex 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +18 -17
- data/README.md +5 -7
- data/Rakefile +3 -3
- data/ffi-struct_ex.gemspec +2 -0
- data/lib/ffi/struct_ex/version.rb +1 -1
- data/spec/ffi/spec_helper.rb +0 -0
- data/spec/ffi/struct_ex_spec.rb +328 -0
- metadata +20 -7
- data/.project +0 -18
- data/test/test_helper.rb +0 -1
- data/test/test_struct_ex.rb +0 -348
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56f6bae584293791faa95b89f433bc4c507f102f
|
4
|
+
data.tar.gz: 85b5c35bb1e4b3856f27471afe5a28b70d788fb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f16a542162f3f97513d5abf8a147beae7f0c17106f68c2ea4327098c72b44ab290ff0950c10601abb6097d02280ec30760a4c82c7f9048b2b491bbdff2b768af
|
7
|
+
data.tar.gz: c9f4858659612519aece832f58cbcbd708a7596d0688016ee46be9646308fc22b88dad18bc58fcb92692499611251e05bc6469b2b35921a8e98268759c6e33dc
|
data/.gitignore
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
test/
|
17
|
-
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
.project
|
7
|
+
Gemfile.lock
|
8
|
+
InstalledFiles
|
9
|
+
_yardoc
|
10
|
+
coverage
|
11
|
+
doc/
|
12
|
+
lib/bundler/man
|
13
|
+
pkg
|
14
|
+
rdoc
|
15
|
+
spec/reports
|
16
|
+
test/tmp
|
17
|
+
test/version_tmp
|
18
|
+
tmp
|
data/README.md
CHANGED
@@ -38,13 +38,13 @@ subject[:bits_0_2] #=> 1
|
|
38
38
|
subject[:bits_5_7] #=> -4
|
39
39
|
```
|
40
40
|
|
41
|
-
* Struct (embedded
|
41
|
+
* Struct (embedded struct)
|
42
42
|
|
43
43
|
```ruby
|
44
44
|
require 'ffi/struct_ex'
|
45
45
|
|
46
46
|
class Subject < FFI::StructEx
|
47
|
-
layout :field_0,
|
47
|
+
layout :field_0, struct_ex(:bits_0_2, 3,
|
48
48
|
:bit_3, 1,
|
49
49
|
:bit_4, 1,
|
50
50
|
:bits_5_7, 3),
|
@@ -56,19 +56,17 @@ end
|
|
56
56
|
subject[:field_0].class.superclass #=> FFI::StructEx
|
57
57
|
|
58
58
|
subject[:field_0] = 0b0110_1001
|
59
|
-
subject[:field_0].
|
59
|
+
subject[:field_0].pointer.read_uint8 #=> 0b0110_1001
|
60
60
|
|
61
61
|
subject[:field_0][:bits_0_2] = 0b101
|
62
62
|
subject[:field_0][:bits_0_2] #=> 0b101
|
63
|
-
subject[:field_0].
|
63
|
+
subject[:field_0].pointer.read_uint8 #=> 0b0110_1101
|
64
64
|
|
65
65
|
subject[:field_0] = {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011}
|
66
|
-
subject[:field_0].
|
66
|
+
subject[:field_0].pointer.read_uint8 #=> 0b0110_1001
|
67
67
|
|
68
68
|
#Equality check
|
69
69
|
subject[:field_0] == {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011} #=> true
|
70
|
-
subject[:field_0] == 0b0110_1001 #=> true
|
71
|
-
subject[:field_0] == '0b0110_1001' #=> true
|
72
70
|
```
|
73
71
|
|
74
72
|
## Contributing
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
3
|
require "bundler/gem_tasks"
|
4
|
-
require '
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
|
-
|
7
|
-
t.
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
7
|
+
t.ruby_opts = "-w -I\"#{['lib', 'spec'].join(File::PATH_SEPARATOR)}\""
|
8
8
|
end
|
data/ffi-struct_ex.gemspec
CHANGED
File without changes
|
@@ -0,0 +1,328 @@
|
|
1
|
+
require 'ffi/spec_helper'
|
2
|
+
require 'ffi/struct_ex/struct_ex'
|
3
|
+
|
4
|
+
|
5
|
+
describe FFI::StructEx do
|
6
|
+
describe "#size and #alignment" do
|
7
|
+
def test_size_and_alignment(specs, size, alignment)
|
8
|
+
klass = Class.new(described_class) do
|
9
|
+
layout(*specs)
|
10
|
+
end
|
11
|
+
|
12
|
+
klass.size.should == size
|
13
|
+
klass.alignment.should == alignment
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should work by declaring ffi type" do
|
17
|
+
test_size_and_alignment([:f0, :short,
|
18
|
+
:f1, :char,
|
19
|
+
:f2, :char], 4, 2)
|
20
|
+
|
21
|
+
test_size_and_alignment([:f0, :short,
|
22
|
+
:f1, :char], 4, 2)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should work by only declaring bit field with default type" do
|
26
|
+
test_size_and_alignment([:f0, 31,
|
27
|
+
:f1, 31], 8, 4)
|
28
|
+
|
29
|
+
test_size_and_alignment([:f0, 8,
|
30
|
+
:f1, 16], 4, 2)
|
31
|
+
test_size_and_alignment([:f0, 16,
|
32
|
+
:f1, 8], 4, 2)
|
33
|
+
|
34
|
+
test_size_and_alignment([:f0, 1,
|
35
|
+
:f1, 16,
|
36
|
+
:f2, 1], 6, 2)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should work by declaring bit field with descriptors and offset" do
|
40
|
+
test_size_and_alignment([:f0, 31, {'1st' => 0xff},
|
41
|
+
:f1, 31], 8, 4)
|
42
|
+
|
43
|
+
test_size_and_alignment([:f0, 8, {'1st' => 0xff},
|
44
|
+
:f1, :short, 4, {'1st' => 0xff}], 6, 2)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should work by only declaring bit field with explicit type" do
|
48
|
+
test_size_and_alignment([:f0, 'uint8: 1'], 1, 1)
|
49
|
+
test_size_and_alignment([:f0, 'uint16: 1'], 2, 2)
|
50
|
+
test_size_and_alignment([:f0, 'uint32: 1'], 4, 4)
|
51
|
+
|
52
|
+
test_size_and_alignment([:f0, 'uint16: 3',
|
53
|
+
:f1, 'uint16: 1',
|
54
|
+
:f2, 'uint16: 1',
|
55
|
+
:f3, 'uint16: 3',
|
56
|
+
:f4, 'uint16: 8'], 2, 2)
|
57
|
+
|
58
|
+
test_size_and_alignment([:f0, 'uint8: 1',
|
59
|
+
:f1, 'uint8: 1'], 1, 1)
|
60
|
+
|
61
|
+
test_size_and_alignment([:f0, 'uint8: 1',
|
62
|
+
:f1, 'int8: 1'], 1, 1)
|
63
|
+
|
64
|
+
test_size_and_alignment([:f0, 'uint8: 1',
|
65
|
+
:f1, 'uint32: 1'], 8, 4)
|
66
|
+
test_size_and_alignment([:f0, 'uint32: 1',
|
67
|
+
:f1, 'uint8: 1'], 8, 4)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should work by declaring bit field and ffi type" do
|
71
|
+
test_size_and_alignment([:f0, 31,
|
72
|
+
:f1, :uint8], 8, 4)
|
73
|
+
|
74
|
+
test_size_and_alignment([:f0, 1,
|
75
|
+
:f1, :uint32], 8, 4)
|
76
|
+
|
77
|
+
test_size_and_alignment([:f0, 4,
|
78
|
+
:f1, 4,
|
79
|
+
:f2, 8,
|
80
|
+
:f3, :uint8], 3, 1)
|
81
|
+
|
82
|
+
test_size_and_alignment([:f0, 1,
|
83
|
+
:f1, 1,
|
84
|
+
:f2, :uint8], 2, 1)
|
85
|
+
|
86
|
+
test_size_and_alignment([:f0, 1,
|
87
|
+
:f1, 1,
|
88
|
+
:f2, :uint8,
|
89
|
+
:f3, 1,
|
90
|
+
:f4, 1], 3, 1)
|
91
|
+
|
92
|
+
test_size_and_alignment([:f0, 1,
|
93
|
+
:f1, 1,
|
94
|
+
:f2, :uint16,
|
95
|
+
:f3, 1,
|
96
|
+
:f4, 1], 6, 2)
|
97
|
+
|
98
|
+
test_size_and_alignment([:f0, 1,
|
99
|
+
:f1, 1,
|
100
|
+
:f2, :uint16,
|
101
|
+
:f3, 1,
|
102
|
+
:f4, 8], 6, 2)
|
103
|
+
|
104
|
+
test_size_and_alignment([:f0, 'uint32: 1',
|
105
|
+
:f1, :uint16], 8, 4)
|
106
|
+
|
107
|
+
test_size_and_alignment([:f0, 'uint8: 1',
|
108
|
+
:f1, :uint32], 8, 4)
|
109
|
+
|
110
|
+
test_size_and_alignment([:f0, :short,
|
111
|
+
:f1, 'char: 1'], 4, 2)
|
112
|
+
|
113
|
+
test_size_and_alignment([:f0, :char,
|
114
|
+
:f1, 'short: 1'], 4, 2)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should work by declaring bit field with typedefed type and ffi type" do
|
118
|
+
FFI.typedef :uint8, :UINT8
|
119
|
+
test_size_and_alignment([:f0, 'UINT8: 8',
|
120
|
+
:f1, 'int: 1'], 8, 4)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#==" do
|
125
|
+
context "when given embedded struct" do
|
126
|
+
let(:hash) { {f0: {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011}, f1: 0x1} }
|
127
|
+
|
128
|
+
subject {
|
129
|
+
Class.new(described_class) do
|
130
|
+
layout :f0, struct_ex(:bits_0_2, 3,
|
131
|
+
:bit_3, 1,
|
132
|
+
:bit_4, 1,
|
133
|
+
:bits_5_7, 3),
|
134
|
+
:f1, :uint8
|
135
|
+
end.new(hash)
|
136
|
+
}
|
137
|
+
|
138
|
+
it "should equal to hash" do
|
139
|
+
subject.should == hash
|
140
|
+
subject[:f0].to_ptr.read_uint8.should == 0b0110_1001
|
141
|
+
subject[:f1].should == hash[:f1]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#initialize" do
|
147
|
+
let(:klass) {
|
148
|
+
Class.new(described_class) do
|
149
|
+
layout :f0, struct_ex(:bits_0_2, 3,
|
150
|
+
:bit_3, 1,
|
151
|
+
:bit_4, 1,
|
152
|
+
:bits_5_7, 3),
|
153
|
+
:f1, :uint8
|
154
|
+
end
|
155
|
+
}
|
156
|
+
|
157
|
+
context "when given empty parameters" do
|
158
|
+
subject { klass.new }
|
159
|
+
|
160
|
+
it "should be initialized as 0" do
|
161
|
+
subject[:f0].pointer.read_uint8.should == 0
|
162
|
+
subject[:f1].should == 0
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when given hash" do
|
167
|
+
let(:hash) { {f0: {bits_0_2: 0b111, bit_3: 0b0, bit_4: 0b0, bits_5_7: 0b101}, f1: 0x12} }
|
168
|
+
subject { klass.new(hash) }
|
169
|
+
|
170
|
+
it "should be initialized as hash" do
|
171
|
+
subject.should == hash
|
172
|
+
subject[:f0].should == hash[:f0]
|
173
|
+
subject[:f0].pointer.read_uint8.should == 0b101_0_0_111
|
174
|
+
subject[:f1].should == hash[:f1]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "#[]" do
|
180
|
+
context "when given signed integer type" do
|
181
|
+
let(:klass) {
|
182
|
+
Class.new(FFI::StructEx) do
|
183
|
+
layout :f0, 'uint8: 3',
|
184
|
+
:f1, 'char: 1',
|
185
|
+
:f2, 'uint8: 1',
|
186
|
+
:f3, 'char: 3'
|
187
|
+
end
|
188
|
+
}
|
189
|
+
|
190
|
+
subject { klass.new(f0: 0b001, f1: 0b1, f2: 0b1, f3: 0b100) }
|
191
|
+
|
192
|
+
it "should be read as signed integer" do
|
193
|
+
subject[:f0].should == 1
|
194
|
+
subject[:f1].should == -1
|
195
|
+
subject[:f2].should == 1
|
196
|
+
subject[:f3].should == -4
|
197
|
+
|
198
|
+
subject[:f3] = 0b010
|
199
|
+
subject[:f3].should == 2
|
200
|
+
|
201
|
+
subject[:f3] = 0
|
202
|
+
subject[:f3].should == 0
|
203
|
+
|
204
|
+
subject[:f3] = 0b110
|
205
|
+
subject[:f3].should == -2
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "#[]=" do
|
211
|
+
context "when given ffi type struct with textual descriptors" do
|
212
|
+
let(:klass) {
|
213
|
+
Class.new(FFI::StructEx) do
|
214
|
+
layout :f0, :uint8, {'all_1' => 0xff, 'all_0' => 0x00},
|
215
|
+
:f1, :uint8, {3 => 1}
|
216
|
+
end
|
217
|
+
}
|
218
|
+
|
219
|
+
subject { klass.new(f0: 'all_1', f1: 0x12) }
|
220
|
+
|
221
|
+
it "should be written with textual descriptor" do
|
222
|
+
subject[:f0].should == 0xff
|
223
|
+
subject[:f1].should == 0x12
|
224
|
+
|
225
|
+
subject[:f0] = 'all_0'
|
226
|
+
subject[:f0].should == 0x00
|
227
|
+
|
228
|
+
subject[:f0] = 0x12
|
229
|
+
subject[:f0].should == 0x12
|
230
|
+
|
231
|
+
subject[:f1] = 3
|
232
|
+
subject[:f1].should == 1
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "when given bit field type struct with textual descriptors" do
|
237
|
+
let(:klass) {
|
238
|
+
Class.new(FFI::StructEx) do
|
239
|
+
layout :f0, 3, {'all_1' => 0b111, 'all_0' => 0b000},
|
240
|
+
:f1, 1, {'yes' => 0b1, 'no' => 0b0},
|
241
|
+
:f2, 1,
|
242
|
+
:f3, :uint8
|
243
|
+
end
|
244
|
+
}
|
245
|
+
|
246
|
+
subject { klass.new(f0: 'all_1', f1: 'yes') }
|
247
|
+
|
248
|
+
it "should be written with textual descriptor" do
|
249
|
+
subject[:f0].should == 0b111
|
250
|
+
subject[:f1].should == 0b1
|
251
|
+
subject[:f2].should == 0
|
252
|
+
subject[:f3].should == 0
|
253
|
+
|
254
|
+
subject[:f0] = 'all_0'
|
255
|
+
subject[:f0].should == 0x00
|
256
|
+
|
257
|
+
subject[:f0] = 0b010
|
258
|
+
subject[:f0].should == 0b010
|
259
|
+
|
260
|
+
subject[:f1] = 'no'
|
261
|
+
subject[:f1].should == 0
|
262
|
+
|
263
|
+
subject[:f1] = 1
|
264
|
+
subject[:f1].should == 1
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "when given embedded struct" do
|
269
|
+
let(:klass) {
|
270
|
+
Class.new(FFI::StructEx) do
|
271
|
+
layout :f0, struct_ex(:bits_0_2, 'uint16: 3',
|
272
|
+
:bit_3, 'uint16: 1',
|
273
|
+
:bit_4, 'uint16: 1',
|
274
|
+
:bits_5_7, 'uint16: 3',
|
275
|
+
:bits_8_15, :uint8),
|
276
|
+
:f1, :uint8,
|
277
|
+
:f2, :uint8,
|
278
|
+
:f3, :uint8
|
279
|
+
end
|
280
|
+
}
|
281
|
+
|
282
|
+
subject { klass.new }
|
283
|
+
|
284
|
+
it "should be written for embeded field" do
|
285
|
+
klass.offset_of(:f1).should == 4
|
286
|
+
|
287
|
+
subject[:f0].class.superclass.should == FFI::StructEx
|
288
|
+
subject[:f0].size.should == 4
|
289
|
+
subject[:f0].alignment.should == 2
|
290
|
+
|
291
|
+
subject[:f0].to_ptr.write_uint16(0b0110_1001)
|
292
|
+
subject[:f0].to_ptr.read_uint16.should == 0b0110_1001
|
293
|
+
subject[:f0][:bits_0_2].should == 0b001
|
294
|
+
|
295
|
+
subject[:f0][:bits_0_2] = 0b101
|
296
|
+
subject[:f0][:bits_0_2].should == 0b101
|
297
|
+
subject[:f0].to_ptr.read_uint16.should == 0b0110_1101
|
298
|
+
|
299
|
+
subject[:f0] = {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011}
|
300
|
+
subject[:f0].to_ptr.read_uint16.should == 0b0110_1001
|
301
|
+
subject[:f0][:bits_0_2].should == 0b001
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
describe "#pointer.write" do
|
307
|
+
let(:klass) {
|
308
|
+
Class.new(FFI::StructEx) do
|
309
|
+
layout :f0, 3,
|
310
|
+
:f1, 1,
|
311
|
+
:f2, 1,
|
312
|
+
:f3, 3
|
313
|
+
end
|
314
|
+
}
|
315
|
+
|
316
|
+
subject { klass.new }
|
317
|
+
|
318
|
+
it "should write" do
|
319
|
+
subject.pointer.write_uint8(0b0110_1001)
|
320
|
+
|
321
|
+
subject[:f0].should == 0b001
|
322
|
+
subject[:f1].should == 0b1
|
323
|
+
subject[:f2].should == 0b0
|
324
|
+
subject[:f3].should == 0b011
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-struct_ex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruijia Li
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: A module to add extra functionalities to FFI::Struct
|
56
70
|
email:
|
57
71
|
- ruijia.li@gmail.com
|
@@ -61,7 +75,6 @@ extra_rdoc_files: []
|
|
61
75
|
files:
|
62
76
|
- .gitattributes
|
63
77
|
- .gitignore
|
64
|
-
- .project
|
65
78
|
- Gemfile
|
66
79
|
- LICENSE.txt
|
67
80
|
- README.md
|
@@ -70,8 +83,8 @@ files:
|
|
70
83
|
- lib/ffi/struct_ex.rb
|
71
84
|
- lib/ffi/struct_ex/struct_ex.rb
|
72
85
|
- lib/ffi/struct_ex/version.rb
|
73
|
-
-
|
74
|
-
-
|
86
|
+
- spec/ffi/spec_helper.rb
|
87
|
+
- spec/ffi/struct_ex_spec.rb
|
75
88
|
homepage: https://github.com/rli9/ffi-struct_ex
|
76
89
|
licenses:
|
77
90
|
- MIT
|
@@ -97,5 +110,5 @@ signing_key:
|
|
97
110
|
specification_version: 4
|
98
111
|
summary: A module to add extra functionalities to FFI::Struct
|
99
112
|
test_files:
|
100
|
-
-
|
101
|
-
-
|
113
|
+
- spec/ffi/spec_helper.rb
|
114
|
+
- spec/ffi/struct_ex_spec.rb
|
data/.project
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<projectDescription>
|
3
|
-
<name>ffi-struct_ex</name>
|
4
|
-
<comment></comment>
|
5
|
-
<projects>
|
6
|
-
</projects>
|
7
|
-
<buildSpec>
|
8
|
-
<buildCommand>
|
9
|
-
<name>com.aptana.ide.core.unifiedBuilder</name>
|
10
|
-
<arguments>
|
11
|
-
</arguments>
|
12
|
-
</buildCommand>
|
13
|
-
</buildSpec>
|
14
|
-
<natures>
|
15
|
-
<nature>com.aptana.ruby.core.rubynature</nature>
|
16
|
-
<nature>com.aptana.projects.webnature</nature>
|
17
|
-
</natures>
|
18
|
-
</projectDescription>
|
data/test/test_helper.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
|
data/test/test_struct_ex.rb
DELETED
@@ -1,348 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'test/unit'
|
3
|
-
require 'ffi/struct_ex'
|
4
|
-
|
5
|
-
class TestStructEx < Test::Unit::TestCase
|
6
|
-
def test_struct_ex
|
7
|
-
subject_class = Class.new(FFI::StructEx) do
|
8
|
-
layout :field_0, struct_ex(:bits_0_2, 'uint16: 3',
|
9
|
-
:bit_3, 'uint16: 1',
|
10
|
-
:bit_4, 'uint16: 1',
|
11
|
-
:bits_5_7, 'uint16: 3',
|
12
|
-
:bits_8_15, :uint8),
|
13
|
-
:field_1, :uint8,
|
14
|
-
:field_2, :uint8,
|
15
|
-
:field_3, :uint8
|
16
|
-
end
|
17
|
-
|
18
|
-
assert_equal(8, subject_class.size)
|
19
|
-
assert_equal(2, subject_class.alignment)
|
20
|
-
assert_equal(4, subject_class.offset_of(:field_1))
|
21
|
-
|
22
|
-
subject = subject_class.new
|
23
|
-
|
24
|
-
assert_equal(FFI::StructEx, subject[:field_0].class.superclass)
|
25
|
-
assert_equal(4, subject[:field_0].size)
|
26
|
-
assert_equal(2, subject[:field_0].alignment)
|
27
|
-
|
28
|
-
subject[:field_0].to_ptr.write_uint16(0b0110_1001)
|
29
|
-
assert_equal(0b0110_1001, subject[:field_0].to_ptr.read_uint16)
|
30
|
-
assert_equal(0b001, subject[:field_0][:bits_0_2])
|
31
|
-
|
32
|
-
subject[:field_0][:bits_0_2] = 0b101
|
33
|
-
assert_equal(0b101, subject[:field_0][:bits_0_2])
|
34
|
-
assert_equal(0b0110_1101, subject[:field_0].to_ptr.read_uint16)
|
35
|
-
|
36
|
-
subject[:field_0] = {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011}
|
37
|
-
assert_equal(0b0110_1001, subject[:field_0].to_ptr.read_uint16)
|
38
|
-
assert_equal(0b001, subject[:field_0][:bits_0_2])
|
39
|
-
|
40
|
-
assert_equal(subject[:field_0], {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011, bits_8_15: 0b0})
|
41
|
-
assert_equal(subject[:field_0].to_ptr.read_uint16, 0b0110_1001)
|
42
|
-
|
43
|
-
subject[:field_1] = 1
|
44
|
-
subject[:field_2] = 2
|
45
|
-
subject[:field_3] = 3
|
46
|
-
assert_equal(subject, {field_0: {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011, bits_8_15: 0b0}, field_1: 1, field_2: 2, field_3: 3})
|
47
|
-
|
48
|
-
subject[:field_0] = subject[:field_0].class.new(bits_0_2: 0b111, bit_3: 0b0, bit_4: 0b0, bits_5_7: 0b101, bits_8_15: 0b10011100)
|
49
|
-
assert_equal(subject[:field_0].to_ptr.read_uint32, 0b10011100_00000000_10100111)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_pure_struct_ex
|
53
|
-
subject_class = Class.new(FFI::StructEx) do
|
54
|
-
layout :bits_0_2, 3,
|
55
|
-
:bit_3, 1,
|
56
|
-
:bit_4, 1,
|
57
|
-
:bits_5_7, 3
|
58
|
-
end
|
59
|
-
|
60
|
-
assert_equal(1, subject_class.size)
|
61
|
-
assert_equal(1, subject_class.alignment)
|
62
|
-
|
63
|
-
subject = subject_class.new
|
64
|
-
|
65
|
-
subject[:bits_0_2] = 0b101
|
66
|
-
assert_equal(0b101, subject[:bits_0_2])
|
67
|
-
|
68
|
-
subject[:bit_3] = 0b1
|
69
|
-
assert_equal(0b1, subject[:bit_3])
|
70
|
-
assert_equal(0b101, subject[:bits_0_2])
|
71
|
-
|
72
|
-
subject = subject_class.new
|
73
|
-
subject.to_ptr.write_uint8(0b0110_1001)
|
74
|
-
assert_equal(0b001, subject[:bits_0_2])
|
75
|
-
assert_equal(0b1, subject[:bit_3])
|
76
|
-
assert_equal(0b0, subject[:bit_4])
|
77
|
-
assert_equal(0b011, subject[:bits_5_7])
|
78
|
-
|
79
|
-
subject = subject_class.new(bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011)
|
80
|
-
assert_equal(0b001, subject[:bits_0_2])
|
81
|
-
assert_equal(0b1, subject[:bit_3])
|
82
|
-
assert_equal(0b0, subject[:bit_4])
|
83
|
-
assert_equal(0b011, subject[:bits_5_7])
|
84
|
-
assert_equal(0b0110_1001, subject.to_ptr.read_uint8)
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_interpreted_struct_ex
|
88
|
-
subject_class = Class.new(FFI::StructEx) do
|
89
|
-
layout :bits_0_2, 3, {'all_1' => 0b111, 'all_0' => 0b000},
|
90
|
-
:bit_3, 1, {'yes' => 0b1, 'no' => 0b0},
|
91
|
-
:bit_4, 1,
|
92
|
-
:bits_5_7, 3
|
93
|
-
end
|
94
|
-
|
95
|
-
subject = subject_class.new(bits_0_2: 'all_1', bit_3: 'yes')
|
96
|
-
assert_equal(0b111, subject[:bits_0_2])
|
97
|
-
assert_equal(0b1, subject[:bit_3])
|
98
|
-
assert_equal(0b0, subject[:bit_4])
|
99
|
-
assert_equal(0b0, subject[:bits_5_7])
|
100
|
-
|
101
|
-
subject[:bits_0_2] = 'all_0'
|
102
|
-
assert_equal(0b000, subject[:bits_0_2])
|
103
|
-
|
104
|
-
subject[:bits_0_2] = 0b010
|
105
|
-
assert_equal(0b010, subject[:bits_0_2])
|
106
|
-
|
107
|
-
subject[:bit_3] = 'no'
|
108
|
-
assert_equal(0b0, subject[:bit_3])
|
109
|
-
|
110
|
-
subject[:bit_3] = 1
|
111
|
-
assert_equal(0b1, subject[:bit_3])
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_equality
|
115
|
-
subject_class = Class.new(FFI::StructEx) do
|
116
|
-
layout :field_0, struct_ex(:bits_0_2, 3,
|
117
|
-
:bit_3, 1,
|
118
|
-
:bit_4, 1,
|
119
|
-
:bits_5_7, 3),
|
120
|
-
:field_1, :uint8
|
121
|
-
end
|
122
|
-
|
123
|
-
subject = subject_class.new(field_0: {bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b0, bits_5_7: 0b011}, field_1: 0x1)
|
124
|
-
|
125
|
-
assert_equal(FFI::StructEx, subject[:field_0].class.superclass)
|
126
|
-
assert_equal(1, subject[:field_0].size)
|
127
|
-
assert_equal(0b0110_1001, subject[:field_0].to_ptr.read_uint8)
|
128
|
-
assert_equal(subject[:field_1], subject.map_field_value(:field_1, '0x1'))
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_descriptors
|
132
|
-
subject_class = Class.new(FFI::StructEx) do
|
133
|
-
layout :field_0, :uint8, {'all_1' => 0xff, 'all_0' => 0x00},
|
134
|
-
:field_1, :uint8, {3 => 1}
|
135
|
-
end
|
136
|
-
|
137
|
-
assert_equal(2, subject_class.size)
|
138
|
-
assert_equal(1, subject_class.alignment)
|
139
|
-
assert_equal(1, subject_class.offset_of(:field_1))
|
140
|
-
|
141
|
-
subject = subject_class.new(field_0: 'all_1', field_1: 0x12)
|
142
|
-
|
143
|
-
assert_equal(0xff, subject[:field_0])
|
144
|
-
assert_equal(0x12, subject[:field_1])
|
145
|
-
|
146
|
-
subject[:field_0] = 'all_0'
|
147
|
-
assert_equal(0x00, subject[:field_0])
|
148
|
-
|
149
|
-
subject[:field_0] = 0x12
|
150
|
-
assert_equal(0x12, subject[:field_0])
|
151
|
-
|
152
|
-
subject[:field_1] = 3
|
153
|
-
assert_equal(0x1, subject[:field_1])
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_initialized_memory_should_be_zero
|
157
|
-
subject_class = Class.new(FFI::StructEx) do
|
158
|
-
layout :field_0, struct_ex(:bits_0_2, 3,
|
159
|
-
:bit_3, 1,
|
160
|
-
:bit_4, 1,
|
161
|
-
:bits_5_7, 3),
|
162
|
-
:field_1, :uint8
|
163
|
-
end
|
164
|
-
|
165
|
-
subject = subject_class.new
|
166
|
-
|
167
|
-
assert_equal(0x00, subject[:field_0].to_ptr.read_uint8)
|
168
|
-
assert_equal(0x00, subject[:field_1])
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_sizeof
|
172
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
173
|
-
layout :field_0, :short,
|
174
|
-
:field_1, :char,
|
175
|
-
:field_2, :char
|
176
|
-
end.size)
|
177
|
-
|
178
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
179
|
-
layout :field_0, 31,
|
180
|
-
:field_1, 31
|
181
|
-
end.size)
|
182
|
-
|
183
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
184
|
-
layout :field_0, 31,
|
185
|
-
:field_1, :uint8
|
186
|
-
end.size)
|
187
|
-
|
188
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
189
|
-
layout :field_0, 1,
|
190
|
-
:field_1, :uint32
|
191
|
-
end.size)
|
192
|
-
|
193
|
-
assert_equal(3, Class.new(FFI::StructEx) do
|
194
|
-
layout :field_0, 4,
|
195
|
-
:field_1, 4,
|
196
|
-
:field_2, 8,
|
197
|
-
:field_3, :uint8
|
198
|
-
end.size)
|
199
|
-
|
200
|
-
assert_equal(2, Class.new(FFI::StructEx) do
|
201
|
-
layout :field_0, 1,
|
202
|
-
:field_1, 1,
|
203
|
-
:field_2, :uint8
|
204
|
-
end.size)
|
205
|
-
|
206
|
-
assert_equal(3, Class.new(FFI::StructEx) do
|
207
|
-
layout :field_0, 1,
|
208
|
-
:field_1, 1,
|
209
|
-
:field_2, :uint8,
|
210
|
-
:field_3, 1,
|
211
|
-
:field_4, 1
|
212
|
-
end.size)
|
213
|
-
|
214
|
-
assert_equal(6, Class.new(FFI::StructEx) do
|
215
|
-
layout :field_0, 1,
|
216
|
-
:field_1, 1,
|
217
|
-
:field_2, :uint16,
|
218
|
-
:field_3, 1,
|
219
|
-
:field_4, 1
|
220
|
-
end.size)
|
221
|
-
|
222
|
-
assert_equal(6, Class.new(FFI::StructEx) do
|
223
|
-
layout :field_0, 1,
|
224
|
-
:field_1, 1,
|
225
|
-
:field_2, :uint16,
|
226
|
-
:field_3, 1,
|
227
|
-
:field_4, 8
|
228
|
-
end.size)
|
229
|
-
|
230
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
231
|
-
layout :field_0, 8,
|
232
|
-
:field_1, 16
|
233
|
-
end.size)
|
234
|
-
|
235
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
236
|
-
layout :field_0, 16,
|
237
|
-
:field_1, 8
|
238
|
-
end.size)
|
239
|
-
|
240
|
-
assert_equal(6, Class.new(FFI::StructEx) do
|
241
|
-
layout :field_0, 1,
|
242
|
-
:field_1, 16,
|
243
|
-
:field_2, 1
|
244
|
-
end.size)
|
245
|
-
|
246
|
-
assert_equal(1, Class.new(FFI::StructEx) do
|
247
|
-
layout :field_0, 'uint8: 1'
|
248
|
-
end.size)
|
249
|
-
|
250
|
-
assert_equal(2, Class.new(FFI::StructEx) do
|
251
|
-
layout :field_0, 'uint16: 1'
|
252
|
-
end.size)
|
253
|
-
|
254
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
255
|
-
layout :field_0, 'uint32: 1'
|
256
|
-
end.size)
|
257
|
-
|
258
|
-
assert_equal(2, Class.new(FFI::StructEx) do
|
259
|
-
layout :bits_0_2, 'uint16: 3',
|
260
|
-
:bit_3, 'uint16: 1',
|
261
|
-
:bit_4, 'uint16: 1',
|
262
|
-
:bits_5_7, 'uint16: 3',
|
263
|
-
:bits_8_15, 'uint16: 8'
|
264
|
-
end.size)
|
265
|
-
|
266
|
-
assert_equal(1, Class.new(FFI::StructEx) do
|
267
|
-
layout :field_0, 'uint8: 1',
|
268
|
-
:field_1, 'uint8: 1'
|
269
|
-
end.size)
|
270
|
-
|
271
|
-
assert_equal(1, Class.new(FFI::StructEx) do
|
272
|
-
layout :field_0, 'uint8: 1',
|
273
|
-
:field_1, 'int8: 1'
|
274
|
-
end.size)
|
275
|
-
|
276
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
277
|
-
layout :field_0, 'uint32: 1',
|
278
|
-
:field_1, :uint16
|
279
|
-
end.size)
|
280
|
-
|
281
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
282
|
-
layout :field_0, 'uint8: 1',
|
283
|
-
:field_1, :uint32
|
284
|
-
end.size)
|
285
|
-
|
286
|
-
assert_equal(8, Class.new(FFI::StructEx) do
|
287
|
-
layout :field_0, 'uint8: 1',
|
288
|
-
:field_1, 'uint32: 1'
|
289
|
-
end.size)
|
290
|
-
|
291
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
292
|
-
layout :field_0, :short,
|
293
|
-
:field_1, :char
|
294
|
-
end.size)
|
295
|
-
|
296
|
-
assert_equal(4, Class.new(FFI::StructEx) do
|
297
|
-
layout :field_0, :short,
|
298
|
-
:field_1, 'char: 1'
|
299
|
-
end.size)
|
300
|
-
|
301
|
-
subject_class = Class.new(FFI::StructEx) do
|
302
|
-
layout :field_0, :char,
|
303
|
-
:field_1, 'short: 1'
|
304
|
-
end
|
305
|
-
assert_equal(4, subject_class.size)
|
306
|
-
|
307
|
-
subject_class = Class.new(FFI::StructEx) do
|
308
|
-
layout :field_0, 'uint: 8',
|
309
|
-
:field_1, 'int: 1'
|
310
|
-
end
|
311
|
-
assert_equal(4, subject_class.size)
|
312
|
-
subject = subject_class.new
|
313
|
-
subject[:field_0] = 0b0110_1001
|
314
|
-
assert_equal(0b0110_1001, subject[:field_0])
|
315
|
-
subject[:field_0] = 0b1111_1111
|
316
|
-
assert_equal(0b1111_1111, subject[:field_0])
|
317
|
-
|
318
|
-
subject[:field_1] = 1
|
319
|
-
assert_equal(-1, subject[:field_1])
|
320
|
-
subject[:field_1] = 0
|
321
|
-
assert_equal(0, subject[:field_1])
|
322
|
-
subject[:field_1] = -1
|
323
|
-
assert_equal(-1, subject[:field_1])
|
324
|
-
|
325
|
-
#Check no impact for typedef type
|
326
|
-
FFI.typedef :uint8, :UINT8
|
327
|
-
subject_class = Class.new(FFI::StructEx) do
|
328
|
-
layout :field_0, 'UINT8: 8',
|
329
|
-
:field_1, 'int: 1'
|
330
|
-
end
|
331
|
-
|
332
|
-
subject_class = Class.new(FFI::StructEx) do
|
333
|
-
layout :bits_0_2, 'uint8: 3',
|
334
|
-
:bit_3, 'char: 1',
|
335
|
-
:bit_4, 'uint8: 1',
|
336
|
-
:bits_5_7, 'char: 3'
|
337
|
-
end
|
338
|
-
|
339
|
-
assert_equal(1, subject_class.size)
|
340
|
-
|
341
|
-
subject = subject_class.new(bits_0_2: 0b001, bit_3: 0b1, bit_4: 0b1, bits_5_7: 0b100)
|
342
|
-
assert_equal(1, subject[:bits_0_2])
|
343
|
-
assert_equal(-1, subject[:bit_3])
|
344
|
-
assert_equal(1, subject[:bit_4])
|
345
|
-
assert_equal(-4, subject[:bits_5_7])
|
346
|
-
|
347
|
-
end
|
348
|
-
end
|