bindata 1.2.2 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bindata might be problematic. Click here for more details.
- data/ChangeLog +12 -0
- data/NEWS +53 -0
- data/Rakefile +2 -1
- data/examples/NBT.txt +149 -0
- data/examples/ip_address.rb +1 -2
- data/examples/list.rb +124 -0
- data/examples/nbt.rb +195 -0
- data/lib/bindata.rb +4 -3
- data/lib/bindata/alignment.rb +86 -0
- data/lib/bindata/array.rb +21 -29
- data/lib/bindata/base.rb +82 -81
- data/lib/bindata/base_primitive.rb +66 -48
- data/lib/bindata/choice.rb +18 -28
- data/lib/bindata/deprecated.rb +17 -0
- data/lib/bindata/dsl.rb +25 -15
- data/lib/bindata/int.rb +2 -2
- data/lib/bindata/io.rb +8 -6
- data/lib/bindata/offset.rb +91 -0
- data/lib/bindata/primitive.rb +22 -11
- data/lib/bindata/record.rb +40 -10
- data/lib/bindata/sanitize.rb +15 -30
- data/lib/bindata/string.rb +16 -17
- data/lib/bindata/stringz.rb +0 -1
- data/lib/bindata/struct.rb +17 -6
- data/lib/bindata/trace.rb +52 -0
- data/lib/bindata/wrapper.rb +28 -6
- data/manual.haml +56 -10
- data/manual.md +318 -113
- data/spec/alignment_spec.rb +61 -0
- data/spec/array_spec.rb +139 -178
- data/spec/base_primitive_spec.rb +86 -111
- data/spec/base_spec.rb +200 -172
- data/spec/bits_spec.rb +45 -53
- data/spec/choice_spec.rb +91 -87
- data/spec/deprecated_spec.rb +36 -14
- data/spec/float_spec.rb +16 -68
- data/spec/int_spec.rb +26 -27
- data/spec/io_spec.rb +105 -105
- data/spec/lazy_spec.rb +50 -50
- data/spec/primitive_spec.rb +36 -36
- data/spec/record_spec.rb +134 -134
- data/spec/registry_spec.rb +34 -38
- data/spec/rest_spec.rb +8 -11
- data/spec/skip_spec.rb +9 -17
- data/spec/spec_common.rb +4 -0
- data/spec/string_spec.rb +92 -115
- data/spec/stringz_spec.rb +41 -74
- data/spec/struct_spec.rb +132 -153
- data/spec/system_spec.rb +115 -60
- data/spec/wrapper_spec.rb +63 -31
- data/tasks/pkg.rake +1 -1
- metadata +15 -7
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata'
|
5
|
+
|
6
|
+
describe BinData::ResumeByteAlignment do
|
7
|
+
class ResumeAlignmentRecord < BinData::Record
|
8
|
+
bit4 :a
|
9
|
+
resume_byte_alignment
|
10
|
+
bit4 :b
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { ResumeAlignmentRecord.new }
|
14
|
+
|
15
|
+
it "should reset read alignment" do
|
16
|
+
subject.read "\x12\x34"
|
17
|
+
|
18
|
+
subject.a.should == 1
|
19
|
+
subject.b.should == 3
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should reset write alignment" do
|
23
|
+
subject.assign(:a => 2, :b => 7)
|
24
|
+
|
25
|
+
subject.to_binary_s.should == "\x20\x70"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe BinData::BitAligned do
|
30
|
+
it "should not apply to BinData::Primitives" do
|
31
|
+
lambda {
|
32
|
+
class BitAlignedPrimitive < BinData::Primitive
|
33
|
+
bit_aligned
|
34
|
+
end
|
35
|
+
}.should raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
class BitString < BinData::String
|
39
|
+
bit_aligned
|
40
|
+
end
|
41
|
+
|
42
|
+
class BitAlignedRecord < BinData::Record
|
43
|
+
bit4 :preamble
|
44
|
+
bit_string :str, :length => 2
|
45
|
+
bit4 :afterward
|
46
|
+
end
|
47
|
+
|
48
|
+
subject { BitAlignedRecord.new }
|
49
|
+
|
50
|
+
its(:num_bytes) { should == 3 }
|
51
|
+
|
52
|
+
it "should read" do
|
53
|
+
subject.read("\x56\x36\x42")
|
54
|
+
subject.should == {"preamble" => 5, "str" => "cd", "afterward" => 2}
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should write" do
|
58
|
+
subject.assign(:preamble => 5, :str => "ab", :afterward => 1)
|
59
|
+
subject.to_binary_s.should == "\x56\x16\x21"
|
60
|
+
end
|
61
|
+
end
|
data/spec/array_spec.rb
CHANGED
@@ -25,313 +25,274 @@ describe BinData::Array, "when instantiating" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
describe BinData::Array, "with no elements" do
|
28
|
-
|
29
|
-
@data = BinData::Array.new(:type => :example_single)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should be clear" do
|
33
|
-
@data.should be_clear
|
34
|
-
end
|
28
|
+
subject { BinData::Array.new(:type => :example_single) }
|
35
29
|
|
36
|
-
it
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
it "should be empty" do
|
41
|
-
@data.should be_empty
|
42
|
-
end
|
30
|
+
it { should be_clear }
|
31
|
+
it { should be_empty }
|
32
|
+
its(:length) { should be_zero }
|
43
33
|
|
44
34
|
it "should return nil for the first element" do
|
45
|
-
|
35
|
+
subject.first.should be_nil
|
46
36
|
end
|
47
37
|
|
48
38
|
it "should return [] for the first n elements" do
|
49
|
-
|
39
|
+
subject.first(3).should == []
|
50
40
|
end
|
51
41
|
|
52
42
|
it "should return nil for the last element" do
|
53
|
-
|
43
|
+
subject.last.should be_nil
|
54
44
|
end
|
55
45
|
|
56
46
|
it "should return [] for the last n elements" do
|
57
|
-
|
47
|
+
subject.last(3).should == []
|
58
48
|
end
|
59
49
|
end
|
60
50
|
|
61
51
|
describe BinData::Array, "with several elements" do
|
62
|
-
|
52
|
+
subject {
|
63
53
|
type = [:example_single, {:initial_value => lambda { index + 1 }}]
|
64
|
-
|
65
|
-
|
54
|
+
BinData::Array.new(:type => type, :initial_length => 5)
|
55
|
+
}
|
66
56
|
|
67
|
-
it
|
68
|
-
|
69
|
-
|
57
|
+
it { should be_clear }
|
58
|
+
it { should_not be_empty }
|
59
|
+
its(:size) { should == 5 }
|
60
|
+
its(:length) { should == 5 }
|
61
|
+
its(:snapshot) { should == [1, 2, 3, 4, 5] }
|
62
|
+
its(:inspect) { should == "[1, 2, 3, 4, 5]" }
|
70
63
|
|
71
|
-
it "should
|
72
|
-
|
64
|
+
it "should coerce to ::Array if required" do
|
65
|
+
[0].concat(subject).should == [0, 1, 2, 3, 4, 5]
|
73
66
|
end
|
74
67
|
|
75
|
-
it "should
|
76
|
-
|
68
|
+
it "should be able to use methods from Enumerable" do
|
69
|
+
subject.select { |x| (x % 2) == 0 }.should == [2, 4]
|
77
70
|
end
|
78
71
|
|
79
72
|
it "should assign primitive values" do
|
80
|
-
|
81
|
-
|
73
|
+
subject.assign([4, 5, 6])
|
74
|
+
subject.should == [4, 5, 6]
|
82
75
|
end
|
83
76
|
|
84
77
|
it "should assign bindata objects" do
|
85
|
-
|
86
|
-
|
87
|
-
o2 = ExampleSingle.new
|
88
|
-
o2.value = 5
|
89
|
-
o3 = ExampleSingle.new
|
90
|
-
o3.value = 6
|
91
|
-
@data.assign([o1, o2, o3])
|
92
|
-
@data.snapshot.should == [4, 5, 6]
|
78
|
+
subject.assign([ExampleSingle.new(4), ExampleSingle.new(5), ExampleSingle.new(6)])
|
79
|
+
subject.should == [4, 5, 6]
|
93
80
|
end
|
94
81
|
|
95
82
|
it "should assign bindata array" do
|
96
83
|
array = BinData::Array.new(:type => :example_single)
|
97
84
|
array.push(4, 5, 6)
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should coerce to ::Array if required" do
|
103
|
-
[0].concat(@data).should == [0, 1, 2, 3, 4, 5]
|
85
|
+
subject.assign(array)
|
86
|
+
subject.should == [4, 5, 6]
|
104
87
|
end
|
105
88
|
|
106
89
|
it "should return the first element" do
|
107
|
-
|
90
|
+
subject.first.should == 1
|
108
91
|
end
|
109
92
|
|
110
93
|
it "should return the first n elements" do
|
111
|
-
|
112
|
-
|
113
|
-
|
94
|
+
subject[0...3].should == [1, 2, 3]
|
95
|
+
subject.first(3).should == [1, 2, 3]
|
96
|
+
subject.first(99).should == [1, 2, 3, 4, 5]
|
114
97
|
end
|
115
98
|
|
116
99
|
it "should return the last element" do
|
117
|
-
|
118
|
-
|
100
|
+
subject.last.should == 5
|
101
|
+
subject[-1].should == 5
|
119
102
|
end
|
120
103
|
|
121
104
|
it "should return the last n elements" do
|
122
|
-
|
123
|
-
|
105
|
+
subject.last(3).should == [3, 4, 5]
|
106
|
+
subject.last(99).should == [1, 2, 3, 4, 5]
|
124
107
|
|
125
|
-
|
108
|
+
subject[-3, 100].should == [3, 4, 5]
|
126
109
|
end
|
127
110
|
|
128
|
-
it "should
|
129
|
-
|
130
|
-
|
111
|
+
it "should clear" do
|
112
|
+
subject[1] = 8
|
113
|
+
subject.clear
|
114
|
+
subject.should == [1, 2, 3, 4, 5]
|
131
115
|
end
|
132
116
|
|
133
|
-
it "should
|
134
|
-
|
117
|
+
it "should clear a single element" do
|
118
|
+
subject[1] = 8
|
119
|
+
subject[1].clear
|
120
|
+
subject[1].should == 2
|
135
121
|
end
|
136
122
|
|
137
|
-
it "should
|
138
|
-
|
123
|
+
it "should be clear if all elements are clear" do
|
124
|
+
subject[1] = 8
|
125
|
+
subject[1].clear
|
126
|
+
subject.should be_clear
|
139
127
|
end
|
140
128
|
|
141
|
-
it "should
|
142
|
-
|
143
|
-
|
129
|
+
it "should test clear status of individual elements" do
|
130
|
+
subject[1] = 8
|
131
|
+
subject[0].should be_clear
|
132
|
+
subject[1].should_not be_clear
|
144
133
|
end
|
145
134
|
|
146
|
-
it "should
|
147
|
-
|
135
|
+
it "should be able to directly access elements" do
|
136
|
+
subject[1] = 8
|
137
|
+
subject[1].should == 8
|
148
138
|
end
|
149
139
|
|
150
|
-
it "should
|
151
|
-
|
152
|
-
|
140
|
+
it "should symmetrically read and write" do
|
141
|
+
subject[1] = 8
|
142
|
+
str = subject.to_binary_s
|
153
143
|
|
154
|
-
|
155
|
-
|
156
|
-
end
|
144
|
+
subject.clear
|
145
|
+
subject[1].should == 2
|
157
146
|
|
158
|
-
|
159
|
-
|
160
|
-
@data.clear
|
161
|
-
@data.should == [1, 2, 3, 4, 5]
|
147
|
+
subject.read(str)
|
148
|
+
subject[1].should == 8
|
162
149
|
end
|
163
150
|
|
164
|
-
it "should
|
165
|
-
|
166
|
-
@data[1].clear
|
167
|
-
@data[1].should == 2
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should be clear upon creation" do
|
171
|
-
@data.should be_clear
|
151
|
+
it "should identify index of elements" do
|
152
|
+
subject.index(3).should == 2
|
172
153
|
end
|
173
154
|
|
174
|
-
it "should
|
175
|
-
|
176
|
-
@data[1].clear
|
177
|
-
@data.should be_clear
|
155
|
+
it "should return nil for index of non existent element" do
|
156
|
+
subject.index(42).should be_nil
|
178
157
|
end
|
179
158
|
|
180
|
-
it "should
|
181
|
-
|
182
|
-
@data[0].should be_clear
|
183
|
-
@data[1].should_not be_clear
|
159
|
+
it "should have correct debug name" do
|
160
|
+
subject[2].debug_name.should == "obj[2]"
|
184
161
|
end
|
185
162
|
|
186
|
-
it "should
|
187
|
-
|
188
|
-
str = @data.to_binary_s
|
189
|
-
|
190
|
-
@data.clear
|
191
|
-
@data[1].should == 2
|
192
|
-
|
193
|
-
@data.read(str)
|
194
|
-
@data[1].should == 8
|
163
|
+
it "should have correct offset" do
|
164
|
+
subject[2].offset.should == ExampleSingle.new.num_bytes * 2
|
195
165
|
end
|
196
166
|
|
197
|
-
it "should
|
198
|
-
|
167
|
+
it "should have correct num_bytes" do
|
168
|
+
subject.num_bytes.should == 5 * ExampleSingle.new.num_bytes
|
199
169
|
end
|
200
170
|
|
201
|
-
it "should
|
202
|
-
|
171
|
+
it "should have correct num_bytes for individual elements" do
|
172
|
+
subject[0].num_bytes.should == ExampleSingle.new.num_bytes
|
203
173
|
end
|
204
174
|
end
|
205
175
|
|
206
176
|
describe BinData::Array, "when accessing elements" do
|
207
|
-
|
177
|
+
subject {
|
208
178
|
type = [:example_single, {:initial_value => lambda { index + 1 }}]
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
@data[3] = 4
|
214
|
-
@data[4] = 5
|
215
|
-
end
|
179
|
+
data = BinData::Array.new(:type => type, :initial_length => 5)
|
180
|
+
data.assign([1, 2, 3, 4, 5])
|
181
|
+
data
|
182
|
+
}
|
216
183
|
|
217
184
|
it "should insert with positive indexes" do
|
218
|
-
|
219
|
-
|
185
|
+
subject.insert(2, 30, 40)
|
186
|
+
subject.snapshot.should == [1, 2, 30, 40, 3, 4, 5]
|
220
187
|
end
|
221
188
|
|
222
189
|
it "should insert with negative indexes" do
|
223
|
-
|
224
|
-
|
190
|
+
subject.insert(-2, 30, 40)
|
191
|
+
subject.snapshot.should == [1, 2, 3, 4, 30, 40, 5]
|
225
192
|
end
|
226
193
|
|
227
194
|
it "should push" do
|
228
|
-
|
229
|
-
|
195
|
+
subject.push(30, 40)
|
196
|
+
subject.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
|
230
197
|
end
|
231
198
|
|
232
199
|
it "should concat" do
|
233
|
-
|
234
|
-
|
200
|
+
subject.concat([30, 40])
|
201
|
+
subject.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
|
235
202
|
end
|
236
203
|
|
237
204
|
it "should unshift" do
|
238
|
-
|
239
|
-
|
205
|
+
subject.unshift(30, 40)
|
206
|
+
subject.snapshot.should == [30, 40, 1, 2, 3, 4, 5]
|
240
207
|
end
|
241
208
|
|
242
209
|
it "should automatically extend on [index]" do
|
243
|
-
|
244
|
-
|
210
|
+
subject[9].should == 10
|
211
|
+
subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
245
212
|
end
|
246
213
|
|
247
214
|
it "should automatically extend on []=" do
|
248
|
-
|
249
|
-
|
215
|
+
subject[9] = 30
|
216
|
+
subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 30]
|
250
217
|
end
|
251
218
|
|
252
219
|
it "should automatically extend on insert" do
|
253
|
-
|
254
|
-
|
220
|
+
subject.insert(7, 30, 40)
|
221
|
+
subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 30, 40]
|
255
222
|
end
|
256
223
|
|
257
224
|
it "should not extend on at" do
|
258
|
-
|
259
|
-
|
225
|
+
subject.at(9).should be_nil
|
226
|
+
subject.length.should == 5
|
260
227
|
end
|
261
228
|
|
262
229
|
it "should not extend on [start, length]" do
|
263
|
-
|
264
|
-
|
230
|
+
subject[9, 2].should be_nil
|
231
|
+
subject.length.should == 5
|
265
232
|
end
|
266
233
|
|
267
234
|
it "should not extend on [range]" do
|
268
|
-
|
269
|
-
|
235
|
+
subject[9 .. 10].should be_nil
|
236
|
+
subject.length.should == 5
|
270
237
|
end
|
271
238
|
|
272
239
|
it "should raise error on bad input to []" do
|
273
|
-
lambda {
|
274
|
-
lambda {
|
240
|
+
lambda { subject["a"] }.should raise_error(TypeError)
|
241
|
+
lambda { subject[1, "a"] }.should raise_error(TypeError)
|
275
242
|
end
|
276
243
|
end
|
277
244
|
|
278
|
-
describe BinData::Array, "with :read_until
|
279
|
-
before(:each) do
|
280
|
-
read_until = lambda { element == 5 }
|
281
|
-
@data = BinData::Array.new(:type => :int8, :read_until => read_until)
|
282
|
-
end
|
245
|
+
describe BinData::Array, "with :read_until" do
|
283
246
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
end
|
289
|
-
end
|
247
|
+
context "containing +element+" do
|
248
|
+
it "should read until the sentinel is reached" do
|
249
|
+
read_until = lambda { element == 5 }
|
250
|
+
subject = BinData::Array.new(:type => :int8, :read_until => read_until)
|
290
251
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
@data = BinData::Array.new(:type => :int8, :read_until => read_until)
|
252
|
+
subject.read "\x01\x02\x03\x04\x05\x06\x07\x08"
|
253
|
+
subject.should == [1, 2, 3, 4, 5]
|
254
|
+
end
|
295
255
|
end
|
296
256
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
end
|
302
|
-
end
|
257
|
+
context "containing +array+ and +index+" do
|
258
|
+
it "should read until the sentinel is reached" do
|
259
|
+
read_until = lambda { index >= 2 and array[index - 2] == 5 }
|
260
|
+
subject = BinData::Array.new(:type => :int8, :read_until => read_until)
|
303
261
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
str = "\x01\x02\x03"
|
308
|
-
obj.read(str)
|
309
|
-
obj.snapshot.should == [1, 2, 3]
|
262
|
+
subject.read "\x01\x02\x03\x04\x05\x06\x07\x08"
|
263
|
+
subject.should == [1, 2, 3, 4, 5, 6, 7]
|
264
|
+
end
|
310
265
|
end
|
311
266
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
267
|
+
context "== :eof" do
|
268
|
+
it "should read records until eof" do
|
269
|
+
subject = BinData::Array.new(:type => :int8, :read_until => :eof)
|
270
|
+
|
271
|
+
subject.read "\x01\x02\x03"
|
272
|
+
subject.should == [1, 2, 3]
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should read records until eof, ignoring partial records" do
|
276
|
+
subject = BinData::Array.new(:type => :int16be, :read_until => :eof)
|
277
|
+
|
278
|
+
subject.read "\x00\x01\x00\x02\x03"
|
279
|
+
subject.should == [1, 2]
|
280
|
+
end
|
317
281
|
end
|
318
282
|
end
|
319
283
|
|
320
284
|
describe BinData::Array, "nested within an Array" do
|
321
|
-
|
285
|
+
subject {
|
322
286
|
nested_array_params = { :type => [:int8, { :initial_value => :index }],
|
323
287
|
:initial_length => lambda { index + 1 } }
|
324
|
-
|
325
|
-
|
326
|
-
|
288
|
+
BinData::Array.new(:type => [:array, nested_array_params],
|
289
|
+
:initial_length => 3)
|
290
|
+
}
|
327
291
|
|
328
|
-
|
329
|
-
@data.snapshot.should == [ [0], [0, 1], [0, 1, 2] ]
|
330
|
-
end
|
292
|
+
its(:snapshot) { should == [ [0], [0, 1], [0, 1, 2] ] }
|
331
293
|
|
332
294
|
it "should maintain structure when reading" do
|
333
|
-
|
334
|
-
|
335
|
-
@data.snapshot.should == [ [4], [5, 6], [7, 8, 9] ]
|
295
|
+
subject.read "\x04\x05\x06\x07\x08\x09"
|
296
|
+
subject.should == [ [4], [5, 6], [7, 8, 9] ]
|
336
297
|
end
|
337
298
|
end
|