bindata 0.9.1 → 0.9.2
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 +8 -0
- data/TODO +0 -6
- data/lib/bindata.rb +1 -1
- data/lib/bindata/array.rb +52 -25
- data/lib/bindata/base.rb +45 -54
- data/lib/bindata/bits.rb +126 -126
- data/lib/bindata/choice.rb +6 -41
- data/lib/bindata/float.rb +4 -4
- data/lib/bindata/int.rb +14 -14
- data/lib/bindata/multi_value.rb +34 -41
- data/lib/bindata/rest.rb +1 -1
- data/lib/bindata/sanitize.rb +88 -3
- data/lib/bindata/single.rb +7 -17
- data/lib/bindata/single_value.rb +4 -10
- data/lib/bindata/string.rb +3 -3
- data/lib/bindata/stringz.rb +1 -1
- data/lib/bindata/struct.rb +118 -139
- data/spec/array_spec.rb +16 -20
- data/spec/base_spec.rb +21 -18
- data/spec/bits_spec.rb +2 -2
- data/spec/choice_spec.rb +0 -24
- data/spec/multi_value_spec.rb +46 -5
- data/spec/sanitize_spec.rb +50 -36
- data/spec/single_spec.rb +0 -8
- data/spec/struct_spec.rb +29 -43
- metadata +2 -2
data/spec/array_spec.rb
CHANGED
@@ -30,18 +30,10 @@ describe BinData::Array, "with no elements" do
|
|
30
30
|
@data = BinData::Array.new(:type => :int8)
|
31
31
|
end
|
32
32
|
|
33
|
-
it "should not have any field_names" do
|
34
|
-
BinData::Array.all_possible_field_names(nil).should be_empty
|
35
|
-
end
|
36
|
-
|
37
33
|
it "should not be a single_value" do
|
38
34
|
@data.should_not be_single_value
|
39
35
|
end
|
40
36
|
|
41
|
-
it "should have no field names" do
|
42
|
-
@data.field_names.should be_empty
|
43
|
-
end
|
44
|
-
|
45
37
|
it "should return correct length" do
|
46
38
|
@data.length.should be_zero
|
47
39
|
end
|
@@ -79,18 +71,10 @@ describe BinData::Array, "with several elements" do
|
|
79
71
|
@data = BinData::Array.new(:type => type, :initial_length => 5)
|
80
72
|
end
|
81
73
|
|
82
|
-
it "should not have any field_names" do
|
83
|
-
BinData::Array.all_possible_field_names(nil).should be_empty
|
84
|
-
end
|
85
|
-
|
86
74
|
it "should not be a single_value" do
|
87
75
|
@data.should_not be_single_value
|
88
76
|
end
|
89
77
|
|
90
|
-
it "should have no field names" do
|
91
|
-
@data.field_names.should be_empty
|
92
|
-
end
|
93
|
-
|
94
78
|
it "should return a correct snapshot" do
|
95
79
|
@data.snapshot.should == [1, 2, 3, 4, 5]
|
96
80
|
end
|
@@ -134,10 +118,6 @@ describe BinData::Array, "with several elements" do
|
|
134
118
|
@data.num_bytes(0).should == 2
|
135
119
|
end
|
136
120
|
|
137
|
-
it "should have no field_names" do
|
138
|
-
@data.field_names.should be_empty
|
139
|
-
end
|
140
|
-
|
141
121
|
it "should be able to directly access elements" do
|
142
122
|
@data[1] = 8
|
143
123
|
@data[1].should == 8
|
@@ -155,6 +135,12 @@ describe BinData::Array, "with several elements" do
|
|
155
135
|
@data.select { |x| (x % 2) == 0 }.should == [2, 4]
|
156
136
|
end
|
157
137
|
|
138
|
+
it "should automatically extend" do
|
139
|
+
@data[9] = 3
|
140
|
+
@data[8].should == 9
|
141
|
+
@data.length.should == 10
|
142
|
+
end
|
143
|
+
|
158
144
|
it "should clear" do
|
159
145
|
@data[1] = 8
|
160
146
|
@data.clear
|
@@ -167,6 +153,11 @@ describe BinData::Array, "with several elements" do
|
|
167
153
|
@data[1].should == 2
|
168
154
|
end
|
169
155
|
|
156
|
+
it "should clear a single element out of range without extending" do
|
157
|
+
@data.clear(9)
|
158
|
+
@data.length.should == 5
|
159
|
+
end
|
160
|
+
|
170
161
|
it "should be clear upon creation" do
|
171
162
|
@data.clear?.should be_true
|
172
163
|
end
|
@@ -183,6 +174,11 @@ describe BinData::Array, "with several elements" do
|
|
183
174
|
@data.clear?(1).should be_false
|
184
175
|
end
|
185
176
|
|
177
|
+
it "should test clear status of out of range elements without extending" do
|
178
|
+
@data.clear?(9).should be_true
|
179
|
+
@data.length.should == 5
|
180
|
+
end
|
181
|
+
|
186
182
|
it "should read and write correctly" do
|
187
183
|
io = StringIO.new
|
188
184
|
@data[1] = 8
|
data/spec/base_spec.rb
CHANGED
@@ -5,13 +5,13 @@ require 'bindata/base'
|
|
5
5
|
|
6
6
|
class BaseStub < BinData::Base
|
7
7
|
def clear; end
|
8
|
+
def clear?; end
|
8
9
|
def single_value?; end
|
9
|
-
def field_names; end
|
10
|
-
def snapshot; end
|
11
10
|
def done_read; end
|
12
11
|
def _do_read(io) end
|
13
12
|
def _do_write(io) end
|
14
13
|
def _do_num_bytes; end
|
14
|
+
def _snapshot; end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe BinData::Base, "with mandatory parameters" do
|
@@ -220,20 +220,21 @@ describe BinData::Base, "with :adjust_offset" do
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
-
describe BinData::Base, "with :
|
223
|
+
describe BinData::Base, "with :onlyif => false" do
|
224
224
|
before(:all) do
|
225
225
|
eval <<-END
|
226
|
-
class
|
226
|
+
class OnlyIfBase < BaseStub
|
227
227
|
attr_accessor :mock
|
228
228
|
def _do_read(io) mock._do_read(io); end
|
229
229
|
def _do_write(io) mock._do_write(io); end
|
230
230
|
def _do_num_bytes; mock._do_num_bytes; end
|
231
|
+
def _snapshot; mock._snapshot; end
|
231
232
|
end
|
232
233
|
END
|
233
234
|
end
|
234
235
|
|
235
236
|
before(:each) do
|
236
|
-
@obj =
|
237
|
+
@obj = OnlyIfBase.new :onlyif => false
|
237
238
|
@obj.mock = mock('mock')
|
238
239
|
end
|
239
240
|
|
@@ -253,22 +254,27 @@ describe BinData::Base, "with :readwrite => false" do
|
|
253
254
|
@obj.mock.should_not_receive(:_do_num_bytes)
|
254
255
|
@obj.num_bytes.should be_zero
|
255
256
|
end
|
257
|
+
|
258
|
+
it "should have nil snapshot" do
|
259
|
+
@obj.mock.should_not_receive(:_snapshot)
|
260
|
+
@obj.snapshot.should be_nil
|
261
|
+
end
|
256
262
|
end
|
257
263
|
|
258
|
-
describe BinData::Base, "with :
|
264
|
+
describe BinData::Base, "with :readwrite" do
|
259
265
|
before(:all) do
|
260
266
|
eval <<-END
|
261
|
-
class
|
267
|
+
class NoIOBase < BinData::Base
|
262
268
|
public :has_param?, :param
|
263
269
|
end
|
264
270
|
END
|
265
271
|
end
|
266
272
|
|
267
|
-
it "should alias to :
|
268
|
-
obj =
|
269
|
-
obj.should_not have_param(:
|
270
|
-
obj.should have_param(:
|
271
|
-
obj.param(:
|
273
|
+
it "should alias to :onlyif" do
|
274
|
+
obj = NoIOBase.new(:readwrite => "a")
|
275
|
+
obj.should_not have_param(:readwrite)
|
276
|
+
obj.should have_param(:onlyif)
|
277
|
+
obj.param(:onlyif).should == "a"
|
272
278
|
end
|
273
279
|
end
|
274
280
|
|
@@ -276,7 +282,7 @@ describe BinData::Base, "when subclassing" do
|
|
276
282
|
before(:all) do
|
277
283
|
eval <<-END
|
278
284
|
class SubClassOfBase < BinData::Base
|
279
|
-
public :_do_read, :_do_write, :_do_num_bytes
|
285
|
+
public :_do_read, :_do_write, :_do_num_bytes, :_snapshot
|
280
286
|
end
|
281
287
|
END
|
282
288
|
end
|
@@ -286,17 +292,14 @@ describe BinData::Base, "when subclassing" do
|
|
286
292
|
end
|
287
293
|
|
288
294
|
it "should raise errors on unimplemented methods" do
|
289
|
-
lambda {
|
290
|
-
SubClassOfBase.all_possible_field_names(nil)
|
291
|
-
}.should raise_error(NotImplementedError)
|
292
295
|
lambda { @obj.clear }.should raise_error(NotImplementedError)
|
296
|
+
lambda { @obj.clear? }.should raise_error(NotImplementedError)
|
293
297
|
lambda { @obj.single_value? }.should raise_error(NotImplementedError)
|
294
|
-
lambda { @obj.field_names }.should raise_error(NotImplementedError)
|
295
|
-
lambda { @obj.snapshot }.should raise_error(NotImplementedError)
|
296
298
|
lambda { @obj.done_read }.should raise_error(NotImplementedError)
|
297
299
|
lambda { @obj._do_read(nil) }.should raise_error(NotImplementedError)
|
298
300
|
lambda { @obj._do_write(nil) }.should raise_error(NotImplementedError)
|
299
301
|
lambda { @obj._do_num_bytes }.should raise_error(NotImplementedError)
|
302
|
+
lambda { @obj._snapshot }.should raise_error(NotImplementedError)
|
300
303
|
end
|
301
304
|
end
|
302
305
|
|
data/spec/bits_spec.rb
CHANGED
@@ -115,14 +115,14 @@ describe "All bitfields" do
|
|
115
115
|
|
116
116
|
min = 0
|
117
117
|
max = (1 << nbits) - 1
|
118
|
-
range =
|
118
|
+
range = (min .. max)
|
119
119
|
|
120
120
|
values = []
|
121
121
|
values << (min + 1) if range.include?(min + 1)
|
122
122
|
values << (min + 3) if range.include?(min + 3)
|
123
123
|
values << (max - 1) if range.include?(max - 1)
|
124
124
|
|
125
|
-
|
125
|
+
values.each do |val|
|
126
126
|
obj = klass.new
|
127
127
|
obj.value = val
|
128
128
|
str = obj.to_s
|
data/spec/choice_spec.rb
CHANGED
@@ -44,28 +44,6 @@ describe BinData::Choice, "when instantiating" do
|
|
44
44
|
args = {:choices => {nil => :int8}, :selection => 0}
|
45
45
|
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
46
46
|
end
|
47
|
-
|
48
|
-
it "should fail on all_possible_field_names with unsanitized parameters" do
|
49
|
-
lambda {
|
50
|
-
BinData::Choice.all_possible_field_names({})
|
51
|
-
}.should raise_error(ArgumentError)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should return all possible field names for :choices Hash" do
|
55
|
-
choices = {0 => [:struct, {:fields => [[:int8, :a], [:int8, :b]]}],
|
56
|
-
1 => [:struct, {:fields => [[:int8, :c]]}]}
|
57
|
-
args = {:choices => choices, :selection => 0}
|
58
|
-
params = BinData::SanitizedParameters.new(BinData::Choice, args)
|
59
|
-
BinData::Choice.all_possible_field_names(params).should == ["a", "b", "c"]
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should return all possible field names for :choices Array" do
|
63
|
-
choices = [[:struct, {:fields => [[:int8, :a], [:int8, :b]]}],
|
64
|
-
[:struct, {:fields => [[:int8, :c]]}]]
|
65
|
-
args = {:choices => choices, :selection => 0}
|
66
|
-
params = BinData::SanitizedParameters.new(BinData::Choice, args)
|
67
|
-
BinData::Choice.all_possible_field_names(params).should == ["a", "b", "c"]
|
68
|
-
end
|
69
47
|
end
|
70
48
|
|
71
49
|
describe BinData::Choice, "with choices array" do
|
@@ -108,9 +86,7 @@ describe BinData::Choice, "with choices array" do
|
|
108
86
|
it "should delegate methods to the selected single choice" do
|
109
87
|
@chooser.choice = 1
|
110
88
|
|
111
|
-
@data.find_obj_for_name("does_not_exist").should be_nil
|
112
89
|
@data.num_bytes.should == 2
|
113
|
-
@data.field_names.should be_empty
|
114
90
|
end
|
115
91
|
end
|
116
92
|
|
data/spec/multi_value_spec.rb
CHANGED
@@ -182,7 +182,7 @@ describe BinData::MultiValue, "with nested structs" do
|
|
182
182
|
class MultiValueOuter < BinData::MultiValue
|
183
183
|
int8 :a, :initial_value => 6
|
184
184
|
multi_value_inner1 :b, :the_val => :a
|
185
|
-
multi_value_inner2
|
185
|
+
multi_value_inner2 :c
|
186
186
|
end
|
187
187
|
END
|
188
188
|
end
|
@@ -192,20 +192,19 @@ describe BinData::MultiValue, "with nested structs" do
|
|
192
192
|
end
|
193
193
|
|
194
194
|
it "should included nested field names" do
|
195
|
-
@obj.field_names.should == ["a", "b", "
|
195
|
+
@obj.field_names.should == ["a", "b", "c"]
|
196
196
|
end
|
197
197
|
|
198
198
|
it "should access nested fields" do
|
199
199
|
@obj.a.should == 6
|
200
200
|
@obj.b.w.should == 3
|
201
201
|
@obj.b.x.should == 6
|
202
|
-
@obj.y.should
|
202
|
+
@obj.c.y.should == 3
|
203
203
|
end
|
204
204
|
|
205
205
|
it "should return correct offset of" do
|
206
206
|
@obj.offset_of("b").should == 1
|
207
|
-
@obj.offset_of("
|
208
|
-
@obj.offset_of("z").should == 4
|
207
|
+
@obj.offset_of("c").should == 3
|
209
208
|
end
|
210
209
|
end
|
211
210
|
|
@@ -248,3 +247,45 @@ describe BinData::MultiValue, "with an endian defined" do
|
|
248
247
|
io.read.should == expected
|
249
248
|
end
|
250
249
|
end
|
250
|
+
|
251
|
+
describe BinData::MultiValue, "defined recursively" do
|
252
|
+
before(:all) do
|
253
|
+
eval <<-END
|
254
|
+
class RecursiveMultiValue < BinData::MultiValue
|
255
|
+
endian :big
|
256
|
+
uint16 :val
|
257
|
+
uint8 :has_nxt, :value => lambda { nxt.clear? ? 0 : 1 }
|
258
|
+
recursive_multi_value :nxt, :onlyif => lambda { has_nxt > 0 }
|
259
|
+
end
|
260
|
+
END
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should be able to be created" do
|
264
|
+
obj = RecursiveMultiValue.new
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should read" do
|
268
|
+
str = "\x00\x01\x01\x00\x02\x01\x00\x03\x00"
|
269
|
+
obj = RecursiveMultiValue.read(str)
|
270
|
+
obj.val.should == 1
|
271
|
+
obj.nxt.val.should == 2
|
272
|
+
obj.nxt.nxt.val.should == 3
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should be assignable on demand" do
|
276
|
+
obj = RecursiveMultiValue.new
|
277
|
+
obj.val = 13
|
278
|
+
obj.nxt.val = 14
|
279
|
+
obj.nxt.nxt.val = 15
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should write" do
|
283
|
+
obj = RecursiveMultiValue.new
|
284
|
+
obj.val = 5
|
285
|
+
obj.nxt.val = 6
|
286
|
+
obj.nxt.nxt.val = 7
|
287
|
+
obj.to_s.should == "\x00\x05\x01\x00\x06\x01\x00\x07\x00"
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
data/spec/sanitize_spec.rb
CHANGED
@@ -2,25 +2,64 @@
|
|
2
2
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
4
|
require 'bindata/sanitize'
|
5
|
+
require 'bindata/int'
|
5
6
|
|
6
|
-
describe BinData::
|
7
|
+
describe BinData::Sanitizer, "class methods" do
|
8
|
+
it "should resolve type with endian" do
|
9
|
+
BinData::Sanitizer.type_exists?(:int16, :little).should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return if type exists" do
|
13
|
+
BinData::Sanitizer.type_exists?(:int8).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise if type doesn't exist" do
|
17
|
+
BinData::Sanitizer.type_exists?(:does_not_exist).should be_false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should lookup types" do
|
21
|
+
BinData::Sanitizer.lookup(:int16, :little).should == BinData::Int16le
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe BinData::Sanitizer do
|
7
27
|
before(:each) do
|
8
|
-
@
|
9
|
-
@mock.stub!(:accepted_parameters).and_return([:a, :b, :c])
|
28
|
+
@sanitizer = BinData::Sanitizer.new
|
10
29
|
end
|
11
30
|
|
12
|
-
it "should
|
13
|
-
|
31
|
+
it "should raise error on unknown types" do
|
32
|
+
lambda {
|
33
|
+
@sanitizer.sanitize(:does_not_exist, {})
|
34
|
+
}.should raise_error(TypeError)
|
35
|
+
end
|
14
36
|
|
15
|
-
|
16
|
-
|
37
|
+
it "should lookup when endian is set" do
|
38
|
+
@sanitizer.with_endian(:little) do
|
39
|
+
klass, params = @sanitizer.sanitize(:int16, {})
|
40
|
+
klass.should == BinData::Int16le
|
41
|
+
end
|
17
42
|
end
|
18
43
|
|
19
|
-
it "should
|
20
|
-
@
|
44
|
+
it "should nest with_endian calls" do
|
45
|
+
@sanitizer.with_endian(:little) do
|
46
|
+
klass, params = @sanitizer.sanitize(:int16, {})
|
47
|
+
klass.should == BinData::Int16le
|
48
|
+
|
49
|
+
@sanitizer.with_endian(:big) do
|
50
|
+
klass, params = @sanitizer.sanitize(:int16, {})
|
51
|
+
klass.should == BinData::Int16be
|
52
|
+
end
|
53
|
+
|
54
|
+
klass, params = @sanitizer.sanitize(:int16, {})
|
55
|
+
klass.should == BinData::Int16le
|
56
|
+
end
|
57
|
+
end
|
21
58
|
|
22
|
-
|
23
|
-
|
59
|
+
it "should sanitize parameters" do
|
60
|
+
klass, params = @sanitizer.sanitize(:int8, {:value => 3})
|
61
|
+
klass.should == BinData::Int8
|
62
|
+
params.should have_key(:value)
|
24
63
|
end
|
25
64
|
end
|
26
65
|
|
@@ -33,9 +72,6 @@ describe BinData::SanitizedParameters, "with bad input" do
|
|
33
72
|
|
34
73
|
it "should convert keys to symbols" do
|
35
74
|
the_params = {'a' => 1, 'b' => 2, 'e' => 5}
|
36
|
-
@mock.should_receive(:sanitize_parameters).with(the_params).
|
37
|
-
and_return { |params, *rest| params }
|
38
|
-
|
39
75
|
sanitized = BinData::SanitizedParameters.new(@mock, the_params)
|
40
76
|
sanitized.accepted_parameters.should == ({:a => 1, :b => 2})
|
41
77
|
sanitized.extra_parameters.should == ({:e => 5})
|
@@ -43,9 +79,6 @@ describe BinData::SanitizedParameters, "with bad input" do
|
|
43
79
|
|
44
80
|
it "should raise error if parameter has nil value" do
|
45
81
|
the_params = {'a' => 1, 'b' => nil, 'e' => 5}
|
46
|
-
@mock.should_receive(:sanitize_parameters).with(the_params).
|
47
|
-
and_return { |params, *rest| params }
|
48
|
-
|
49
82
|
lambda {
|
50
83
|
BinData::SanitizedParameters.new(@mock, the_params)
|
51
84
|
}.should raise_error(ArgumentError)
|
@@ -59,26 +92,13 @@ describe BinData::SanitizedParameters do
|
|
59
92
|
@params = {:a => 1, :b => 2, :c => 3, :d => 4, :e => 5}
|
60
93
|
end
|
61
94
|
|
62
|
-
it "should pass extra arguments" do
|
63
|
-
@mock.should_receive(:sanitize_parameters).with(@params, 1, 2, 3).
|
64
|
-
and_return { |params, *rest| params }
|
65
|
-
|
66
|
-
sanitized = BinData::SanitizedParameters.new(@mock, @params, 1, 2, 3)
|
67
|
-
end
|
68
|
-
|
69
95
|
it "should partition" do
|
70
|
-
@mock.should_receive(:sanitize_parameters).with(@params).
|
71
|
-
and_return { |params, *rest| params }
|
72
|
-
|
73
96
|
sanitized = BinData::SanitizedParameters.new(@mock, @params)
|
74
97
|
sanitized.accepted_parameters.should == ({:a => 1, :b => 2, :c => 3})
|
75
98
|
sanitized.extra_parameters.should == ({:d => 4, :e => 5})
|
76
99
|
end
|
77
100
|
|
78
101
|
it "should respond_to keys" do
|
79
|
-
@mock.should_receive(:sanitize_parameters).with(@params).
|
80
|
-
and_return { |params, *rest| params }
|
81
|
-
|
82
102
|
sanitized = BinData::SanitizedParameters.new(@mock, @params)
|
83
103
|
sanitized.should respond_to(:keys)
|
84
104
|
keys = sanitized.keys.collect { |x| x.to_s }
|
@@ -86,9 +106,6 @@ describe BinData::SanitizedParameters do
|
|
86
106
|
end
|
87
107
|
|
88
108
|
it "should respond_to has_key?" do
|
89
|
-
@mock.should_receive(:sanitize_parameters).with(@params).
|
90
|
-
and_return { |params, *rest| params }
|
91
|
-
|
92
109
|
sanitized = BinData::SanitizedParameters.new(@mock, @params)
|
93
110
|
sanitized.should respond_to(:has_key?)
|
94
111
|
sanitized.has_key?(:a).should be_true
|
@@ -97,9 +114,6 @@ describe BinData::SanitizedParameters do
|
|
97
114
|
end
|
98
115
|
|
99
116
|
it "should respond_to []" do
|
100
|
-
@mock.should_receive(:sanitize_parameters).with(@params).
|
101
|
-
and_return { |params, *rest| params }
|
102
|
-
|
103
117
|
sanitized = BinData::SanitizedParameters.new(@mock, @params)
|
104
118
|
sanitized.should respond_to(:[])
|
105
119
|
sanitized[:a].should == 1
|