bindata 0.9.3 → 0.10.0
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 +18 -0
- data/NEWS +59 -0
- data/README +22 -23
- data/TODO +18 -12
- data/examples/gzip.rb +4 -4
- data/lib/bindata.rb +4 -3
- data/lib/bindata/array.rb +202 -132
- data/lib/bindata/base.rb +147 -166
- data/lib/bindata/{single.rb → base_primitive.rb} +82 -56
- data/lib/bindata/bits.rb +31 -770
- data/lib/bindata/choice.rb +157 -82
- data/lib/bindata/float.rb +25 -27
- data/lib/bindata/int.rb +144 -177
- data/lib/bindata/io.rb +59 -49
- data/lib/bindata/lazy.rb +80 -50
- data/lib/bindata/params.rb +134 -26
- data/lib/bindata/{single_value.rb → primitive.rb} +71 -64
- data/lib/bindata/{multi_value.rb → record.rb} +52 -70
- data/lib/bindata/registry.rb +49 -17
- data/lib/bindata/rest.rb +6 -10
- data/lib/bindata/sanitize.rb +55 -70
- data/lib/bindata/string.rb +60 -42
- data/lib/bindata/stringz.rb +34 -35
- data/lib/bindata/struct.rb +197 -152
- data/lib/bindata/trace.rb +35 -0
- data/spec/array_spec.rb +128 -112
- data/spec/{single_spec.rb → base_primitive_spec.rb} +102 -61
- data/spec/base_spec.rb +190 -185
- data/spec/bits_spec.rb +126 -98
- data/spec/choice_spec.rb +89 -98
- data/spec/example.rb +19 -0
- data/spec/float_spec.rb +28 -44
- data/spec/int_spec.rb +217 -127
- data/spec/io_spec.rb +41 -24
- data/spec/lazy_spec.rb +95 -49
- data/spec/primitive_spec.rb +191 -0
- data/spec/{multi_value_spec.rb → record_spec.rb} +124 -89
- data/spec/registry_spec.rb +53 -12
- data/spec/rest_spec.rb +2 -3
- data/spec/sanitize_spec.rb +47 -73
- data/spec/spec_common.rb +13 -1
- data/spec/string_spec.rb +34 -23
- data/spec/stringz_spec.rb +10 -18
- data/spec/struct_spec.rb +91 -63
- data/spec/system_spec.rb +291 -0
- metadata +12 -8
- data/spec/single_value_spec.rb +0 -131
data/spec/io_spec.rb
CHANGED
@@ -39,6 +39,13 @@ describe BinData::IO do
|
|
39
39
|
io.readbytes(4).should == "cdef"
|
40
40
|
end
|
41
41
|
|
42
|
+
it "should read all bytes" do
|
43
|
+
stream = StringIO.new("abcdefghij")
|
44
|
+
io = BinData::IO.new(stream)
|
45
|
+
|
46
|
+
io.read_all_bytes.should == "abcdefghij"
|
47
|
+
end
|
48
|
+
|
42
49
|
it "should raise error when reading at eof" do
|
43
50
|
stream = StringIO.new("abcdefghij")
|
44
51
|
io = BinData::IO.new(stream)
|
@@ -64,6 +71,17 @@ describe BinData::IO do
|
|
64
71
|
stream.rewind
|
65
72
|
stream.read.should == "abcd"
|
66
73
|
end
|
74
|
+
|
75
|
+
it "should flush" do
|
76
|
+
stream = StringIO.new
|
77
|
+
io = BinData::IO.new(stream)
|
78
|
+
io.writebytes("abcd")
|
79
|
+
io.flush
|
80
|
+
|
81
|
+
stream.rewind
|
82
|
+
stream.read.should == "abcd"
|
83
|
+
end
|
84
|
+
|
67
85
|
end
|
68
86
|
|
69
87
|
describe BinData::IO, "reading bits in big endian" do
|
@@ -76,36 +94,36 @@ describe BinData::IO, "reading bits in big endian" do
|
|
76
94
|
end
|
77
95
|
|
78
96
|
it "should read a bitfield less than 1 byte" do
|
79
|
-
@io.readbits(3).should == 0b111
|
97
|
+
@io.readbits(3, :big).should == 0b111
|
80
98
|
end
|
81
99
|
|
82
100
|
it "should read a bitfield more than 1 byte" do
|
83
|
-
@io.readbits(10).should == 0b1111_1010_11
|
101
|
+
@io.readbits(10, :big).should == 0b1111_1010_11
|
84
102
|
end
|
85
103
|
|
86
104
|
it "should read a bitfield more than 2 bytes" do
|
87
|
-
@io.readbits(17).should == 0b1111_1010_1100_1110_0
|
105
|
+
@io.readbits(17, :big).should == 0b1111_1010_1100_1110_0
|
88
106
|
end
|
89
107
|
|
90
108
|
it "should read two bitfields totalling less than 1 byte" do
|
91
|
-
@io.readbits(5).should == 0b1111_1
|
92
|
-
@io.readbits(2).should == 0b01
|
109
|
+
@io.readbits(5, :big).should == 0b1111_1
|
110
|
+
@io.readbits(2, :big).should == 0b01
|
93
111
|
end
|
94
112
|
|
95
113
|
it "should read two bitfields totalling more than 1 byte" do
|
96
|
-
@io.readbits(6).should == 0b1111_10
|
97
|
-
@io.readbits(8).should == 0b10_1100_11
|
114
|
+
@io.readbits(6, :big).should == 0b1111_10
|
115
|
+
@io.readbits(8, :big).should == 0b10_1100_11
|
98
116
|
end
|
99
117
|
|
100
118
|
it "should read two bitfields totalling more than 2 bytes" do
|
101
|
-
@io.readbits(7).should == 0b1111_101
|
102
|
-
@io.readbits(12).should == 0b0_1100_1110_011
|
119
|
+
@io.readbits(7, :big).should == 0b1111_101
|
120
|
+
@io.readbits(12, :big).should == 0b0_1100_1110_011
|
103
121
|
end
|
104
122
|
|
105
123
|
it "should ignore unused bits when reading bytes" do
|
106
|
-
@io.readbits(3).should == 0b111
|
124
|
+
@io.readbits(3, :big).should == 0b111
|
107
125
|
@io.readbytes(1).should == [@b2].pack("C")
|
108
|
-
@io.readbits(2).should == 0b01
|
126
|
+
@io.readbits(2, :big).should == 0b01
|
109
127
|
end
|
110
128
|
end
|
111
129
|
|
@@ -158,7 +176,7 @@ class BitWriterHelper
|
|
158
176
|
@io = BinData::IO.new(@stringio)
|
159
177
|
end
|
160
178
|
|
161
|
-
def writebits(val, nbits, endian
|
179
|
+
def writebits(val, nbits, endian)
|
162
180
|
@io.writebits(val, nbits, endian)
|
163
181
|
end
|
164
182
|
|
@@ -179,42 +197,42 @@ describe BinData::IO, "writing bits in big endian" do
|
|
179
197
|
end
|
180
198
|
|
181
199
|
it "should write a bitfield less than 1 byte" do
|
182
|
-
@io.writebits(0b010, 3)
|
200
|
+
@io.writebits(0b010, 3, :big)
|
183
201
|
@io.value.should == [0b0100_0000].pack("C")
|
184
202
|
end
|
185
203
|
|
186
204
|
it "should write a bitfield more than 1 byte" do
|
187
|
-
@io.writebits(0b10_1001_1101, 10)
|
205
|
+
@io.writebits(0b10_1001_1101, 10, :big)
|
188
206
|
@io.value.should == [0b1010_0111, 0b0100_0000].pack("CC")
|
189
207
|
end
|
190
208
|
|
191
209
|
it "should write a bitfield more than 2 bytes" do
|
192
|
-
@io.writebits(0b101_1000_0010_1001_1101, 19)
|
210
|
+
@io.writebits(0b101_1000_0010_1001_1101, 19, :big)
|
193
211
|
@io.value.should == [0b1011_0000, 0b0101_0011, 0b1010_0000].pack("CCC")
|
194
212
|
end
|
195
213
|
|
196
214
|
it "should write two bitfields totalling less than 1 byte" do
|
197
|
-
@io.writebits(0b1_1001, 5)
|
198
|
-
@io.writebits(0b00, 2)
|
215
|
+
@io.writebits(0b1_1001, 5, :big)
|
216
|
+
@io.writebits(0b00, 2, :big)
|
199
217
|
@io.value.should == [0b1100_1000].pack("C")
|
200
218
|
end
|
201
219
|
|
202
220
|
it "should write two bitfields totalling more than 1 byte" do
|
203
|
-
@io.writebits(0b01_0101, 6)
|
204
|
-
@io.writebits(0b001_1001, 7)
|
221
|
+
@io.writebits(0b01_0101, 6, :big)
|
222
|
+
@io.writebits(0b001_1001, 7, :big)
|
205
223
|
@io.value.should == [0b0101_0100, 0b1100_1000].pack("CC")
|
206
224
|
end
|
207
225
|
|
208
226
|
it "should write two bitfields totalling more than 2 bytes" do
|
209
|
-
@io.writebits(0b01_0111, 6)
|
210
|
-
@io.writebits(0b1_0010_1001_1001, 13)
|
227
|
+
@io.writebits(0b01_0111, 6, :big)
|
228
|
+
@io.writebits(0b1_0010_1001_1001, 13, :big)
|
211
229
|
@io.value.should == [0b0101_1110, 0b0101_0011, 0b0010_0000].pack("CCC")
|
212
230
|
end
|
213
231
|
|
214
232
|
it "should pad unused bits when writing bytes" do
|
215
|
-
@io.writebits(0b101, 3)
|
233
|
+
@io.writebits(0b101, 3, :big)
|
216
234
|
@io.writebytes([0b1011_1111].pack("C"))
|
217
|
-
@io.writebits(0b01, 2)
|
235
|
+
@io.writebits(0b01, 2, :big)
|
218
236
|
|
219
237
|
@io.value.should == [0b1010_0000, 0b1011_1111, 0b0100_0000].pack("CCC")
|
220
238
|
end
|
@@ -285,4 +303,3 @@ describe BinData::IO, "with changing endian" do
|
|
285
303
|
io.value.should == [0b1100_0000, 0b0000_0010].pack("CC")
|
286
304
|
end
|
287
305
|
end
|
288
|
-
|
data/spec/lazy_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
-
require 'bindata/array'
|
5
|
-
require 'bindata/int'
|
6
4
|
require 'bindata/lazy'
|
7
5
|
|
8
6
|
# A mock data object with customizable fields.
|
@@ -15,33 +13,51 @@ class MockDataObject
|
|
15
13
|
@parameters = params
|
16
14
|
@parent = parent
|
17
15
|
end
|
18
|
-
attr_accessor :parent
|
16
|
+
attr_accessor :parent
|
17
|
+
|
18
|
+
def has_parameter?(k)
|
19
|
+
@parameters.has_key?(k)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_parameter(k)
|
23
|
+
@parameters[k]
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
27
|
+
# Shortcut to save typing
|
28
|
+
LE = BinData::LazyEvaluator
|
29
|
+
|
21
30
|
describe BinData::LazyEvaluator, "with no parents" do
|
22
31
|
before(:each) do
|
23
32
|
methods = {:m1 => 'm1', :com => 'mC'}
|
24
33
|
params = {:p1 => 'p1', :com => 'pC'}
|
25
|
-
obj = MockDataObject.new(methods, params)
|
26
|
-
|
34
|
+
@obj = MockDataObject.new(methods, params)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should evaluate raw value" do
|
38
|
+
LE.eval(@obj, 5).should == 5
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should evaluate value" do
|
42
|
+
LE.eval(@obj, lambda { 5 }).should == 5
|
27
43
|
end
|
28
44
|
|
29
45
|
it "should evaluate overrides" do
|
30
|
-
|
46
|
+
LE.eval(@obj, lambda { o1 }, :o1 => 'o1').should == 'o1'
|
31
47
|
end
|
32
48
|
|
33
49
|
it "should not resolve any unknown methods" do
|
34
|
-
lambda {
|
35
|
-
lambda {
|
36
|
-
lambda {
|
50
|
+
lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
|
51
|
+
lambda { LE.eval(@obj, lambda { m1 }) }.should raise_error(NameError)
|
52
|
+
lambda { LE.eval(@obj, lambda { p1 }) }.should raise_error(NameError)
|
37
53
|
end
|
38
54
|
|
39
55
|
it "should not have a parent" do
|
40
|
-
|
56
|
+
LE.eval(@obj, lambda { parent }).should be_nil
|
41
57
|
end
|
42
58
|
|
43
59
|
it "should not resolve #index" do
|
44
|
-
lambda {
|
60
|
+
lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
|
45
61
|
end
|
46
62
|
end
|
47
63
|
|
@@ -51,39 +67,57 @@ describe BinData::LazyEvaluator, "with one parent" do
|
|
51
67
|
parent_params = {:p1 => 'Pp1', :com => 'PpC'}
|
52
68
|
parent_obj = MockDataObject.new(parent_methods, parent_params)
|
53
69
|
|
70
|
+
def parent_obj.echo(a1, a2)
|
71
|
+
[a1, a2]
|
72
|
+
end
|
73
|
+
|
54
74
|
methods = {:m1 => 'm1', :com => 'mC'}
|
55
75
|
params = {:p1 => 'p1', :com => 'pC'}
|
56
|
-
obj = MockDataObject.new(methods, params, parent_obj)
|
76
|
+
@obj = MockDataObject.new(methods, params, parent_obj)
|
77
|
+
end
|
57
78
|
|
58
|
-
|
79
|
+
it "should evaluate raw value" do
|
80
|
+
LE.eval(@obj, 5).should == 5
|
59
81
|
end
|
60
82
|
|
61
|
-
it "should evaluate
|
62
|
-
|
83
|
+
it "should evaluate value" do
|
84
|
+
LE.eval(@obj, lambda { 5 }).should == 5
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should evaluate overrides before params" do
|
88
|
+
LE.eval(@obj, lambda { p1 }, :p1 => 'o1').should == 'o1'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should evaluate overrides before methods" do
|
92
|
+
LE.eval(@obj, lambda { m1 }, :m1 => 'o1').should == 'o1'
|
63
93
|
end
|
64
94
|
|
65
95
|
it "should not resolve any unknown methods" do
|
66
|
-
lambda {
|
96
|
+
lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
|
67
97
|
end
|
68
98
|
|
69
99
|
it "should resolve parameters in the parent" do
|
70
|
-
|
100
|
+
LE.eval(@obj, lambda { p1 }).should == 'Pp1'
|
71
101
|
end
|
72
102
|
|
73
103
|
it "should resolve methods in the parent" do
|
74
|
-
|
104
|
+
LE.eval(@obj, lambda { m1 }).should == 'Pm1'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should invoke methods in the parent" do
|
108
|
+
LE.eval(@obj, lambda { echo(p1, m1) }).should == ['Pp1', 'Pm1']
|
75
109
|
end
|
76
110
|
|
77
111
|
it "should resolve parameters in preference to methods in the parent" do
|
78
|
-
|
112
|
+
LE.eval(@obj, lambda { com }).should == 'PpC'
|
79
113
|
end
|
80
114
|
|
81
115
|
it "should have a parent" do
|
82
|
-
|
116
|
+
LE.eval(@obj, lambda { parent }).should_not be_nil
|
83
117
|
end
|
84
118
|
|
85
119
|
it "should not resolve #index" do
|
86
|
-
lambda {
|
120
|
+
lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
|
87
121
|
end
|
88
122
|
end
|
89
123
|
|
@@ -93,68 +127,80 @@ describe BinData::LazyEvaluator, "with nested parents" do
|
|
93
127
|
pparent_params = {:p1 => 'PPp1', :p2 => 'PPp2', :com => 'PPpC'}
|
94
128
|
pparent_obj = MockDataObject.new(pparent_methods, pparent_params)
|
95
129
|
|
96
|
-
|
130
|
+
def pparent_obj.echo(arg)
|
131
|
+
["PP", arg]
|
132
|
+
end
|
133
|
+
|
134
|
+
def pparent_obj.echo2(arg)
|
135
|
+
["PP2", arg]
|
136
|
+
end
|
137
|
+
|
138
|
+
parent_methods = {:m1 => 'Pm1', :com => 'PmC', :sym1 => :m2, :sym2 => lambda { m2 }}
|
97
139
|
parent_params = {:p1 => 'Pp1', :com => 'PpC'}
|
98
140
|
parent_obj = MockDataObject.new(parent_methods, parent_params, pparent_obj)
|
99
141
|
|
142
|
+
def parent_obj.echo(arg)
|
143
|
+
["P", arg]
|
144
|
+
end
|
145
|
+
|
100
146
|
methods = {:m1 => 'm1', :com => 'mC'}
|
101
147
|
params = {:p1 => 'p1', :com => 'pC'}
|
102
|
-
obj = MockDataObject.new(methods, params, parent_obj)
|
103
|
-
|
104
|
-
@ev = BinData::LazyEvaluator.new(obj)
|
148
|
+
@obj = MockDataObject.new(methods, params, parent_obj)
|
105
149
|
end
|
106
150
|
|
107
151
|
it "should accept symbols as a shortcut to lambdas" do
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
152
|
+
LE.eval(@obj, :p1).should == 'Pp1'
|
153
|
+
LE.eval(@obj, :p2).should == 'PPp2'
|
154
|
+
LE.eval(@obj, :m1).should == 'Pm1'
|
155
|
+
LE.eval(@obj, :m2).should == 'PPm2'
|
112
156
|
end
|
113
157
|
|
114
158
|
it "should not resolve any unknown methods" do
|
115
|
-
lambda {
|
159
|
+
lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
|
116
160
|
end
|
117
161
|
|
118
162
|
it "should resolve parameters in the parent" do
|
119
|
-
|
163
|
+
LE.eval(@obj, lambda { p1 }).should == 'Pp1'
|
120
164
|
end
|
121
165
|
|
122
166
|
it "should resolve methods in the parent" do
|
123
|
-
|
167
|
+
LE.eval(@obj, lambda { m1 }).should == 'Pm1'
|
124
168
|
end
|
125
169
|
|
126
170
|
it "should resolve parameters in the parent's parent" do
|
127
|
-
|
171
|
+
LE.eval(@obj, lambda { p2 }).should == 'PPp2'
|
128
172
|
end
|
129
173
|
|
130
174
|
it "should resolve methods in the parent's parent" do
|
131
|
-
|
175
|
+
LE.eval(@obj, lambda { m2 }).should == 'PPm2'
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should invoke methods in the parent" do
|
179
|
+
LE.eval(@obj, lambda { echo(m1) }).should == ['P', 'Pm1']
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should invoke methods in the parent's parent" do
|
183
|
+
LE.eval(@obj, lambda { parent.echo(m1) }, { :m1 => 'o1'}).should == ['PP', 'o1']
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should invoke methods in the parent's parent" do
|
187
|
+
LE.eval(@obj, lambda { echo2(m1) }).should == ['PP2', 'Pm1']
|
132
188
|
end
|
133
189
|
|
134
190
|
it "should resolve parameters in preference to methods in the parent" do
|
135
|
-
|
191
|
+
LE.eval(@obj, lambda { com }).should == 'PpC'
|
136
192
|
end
|
137
193
|
|
138
194
|
it "should resolve methods in the parent explicitly" do
|
139
|
-
|
195
|
+
LE.eval(@obj, lambda { parent.m1 }).should == 'PPm1'
|
140
196
|
end
|
141
197
|
|
142
198
|
it "should cascade lambdas " do
|
143
|
-
|
199
|
+
LE.eval(@obj, lambda { sym1 }).should == 'PPm2'
|
200
|
+
LE.eval(@obj, lambda { sym2 }).should == 'PPm2'
|
144
201
|
end
|
145
202
|
|
146
203
|
it "should not resolve #index" do
|
147
|
-
lambda {
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# This spec seems out of place, but :index is implemented in lazy.rb so this
|
152
|
-
# is the best place for it.
|
153
|
-
describe BinData::LazyEvaluator, "with BinData::Array" do
|
154
|
-
it "should use correct index" do
|
155
|
-
arr = BinData::Array.new(:type =>
|
156
|
-
[:uint8, { :value => lambda { index * 10 } }],
|
157
|
-
:initial_length => 3)
|
158
|
-
arr.snapshot.should == [0, 10, 20]
|
204
|
+
lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
|
159
205
|
end
|
160
206
|
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require 'bindata'
|
5
|
+
|
6
|
+
describe BinData::Primitive, "when subclassing" do
|
7
|
+
before(:all) do
|
8
|
+
eval <<-END
|
9
|
+
class SubClassOfPrimitive < BinData::Primitive
|
10
|
+
expose_methods_for_testing
|
11
|
+
end
|
12
|
+
END
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@obj = SubClassOfPrimitive.new
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise errors on unimplemented methods" do
|
20
|
+
lambda { @obj.set(nil) }.should raise_error(NotImplementedError)
|
21
|
+
lambda { @obj.get }.should raise_error(NotImplementedError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe BinData::Primitive, "when defining" do
|
26
|
+
it "should allow inheriting from deprecated SingleValue" do
|
27
|
+
lambda {
|
28
|
+
eval <<-END
|
29
|
+
class SubclassSingleValue < BinData::SingleValue
|
30
|
+
end
|
31
|
+
END
|
32
|
+
}.should_not raise_error
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should fail on non registered types" do
|
36
|
+
lambda {
|
37
|
+
eval <<-END
|
38
|
+
class BadTypePrimitive < BinData::Primitive
|
39
|
+
non_registered_type :a
|
40
|
+
end
|
41
|
+
END
|
42
|
+
}.should raise_error(TypeError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should fail on duplicate names" do
|
46
|
+
lambda {
|
47
|
+
eval <<-END
|
48
|
+
class DuplicateNamePrimitive < BinData::Primitive
|
49
|
+
int8 :a
|
50
|
+
int8 :b
|
51
|
+
int8 :a
|
52
|
+
end
|
53
|
+
END
|
54
|
+
}.should raise_error(SyntaxError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should fail when field name shadows an existing method" do
|
58
|
+
lambda {
|
59
|
+
eval <<-END
|
60
|
+
class ExistingNamePrimitive < BinData::Primitive
|
61
|
+
int8 :object_id
|
62
|
+
end
|
63
|
+
END
|
64
|
+
}.should raise_error(NameError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should fail on unknown endian" do
|
68
|
+
lambda {
|
69
|
+
eval <<-END
|
70
|
+
class BadEndianPrimitive < BinData::Primitive
|
71
|
+
endian 'a bad value'
|
72
|
+
end
|
73
|
+
END
|
74
|
+
}.should raise_error(ArgumentError)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe BinData::Primitive do
|
79
|
+
before(:all) do
|
80
|
+
eval <<-END
|
81
|
+
class PrimitiveWithEndian < BinData::Primitive
|
82
|
+
endian :little
|
83
|
+
int16 :a
|
84
|
+
def get; self.a; end
|
85
|
+
def set(v); self.a = v; end
|
86
|
+
end
|
87
|
+
END
|
88
|
+
end
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
@obj = PrimitiveWithEndian.new
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should support endian" do
|
95
|
+
@obj.value = 5
|
96
|
+
@obj.to_binary_s.should == "\x05\x00"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should set value" do
|
100
|
+
@obj.value = 5
|
101
|
+
@obj.to_binary_s.should == "\x05\x00"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should read value" do
|
105
|
+
@obj.read("\x00\x01")
|
106
|
+
@obj.value.should == 0x100
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should accept standard parameters" do
|
110
|
+
obj = PrimitiveWithEndian.new(:initial_value => 2)
|
111
|
+
obj.to_binary_s.should == "\x02\x00"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return num_bytes" do
|
115
|
+
@obj.num_bytes.should == 2
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should raise error on missing methods" do
|
119
|
+
lambda {
|
120
|
+
@obj.does_not_exist
|
121
|
+
}.should raise_error(NoMethodError)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe BinData::Primitive, "requiring custom parameters" do
|
126
|
+
before(:all) do
|
127
|
+
eval <<-END
|
128
|
+
class PrimitiveWithCustom < BinData::Primitive
|
129
|
+
int8 :a, :initial_value => :iv
|
130
|
+
def get; self.a; end
|
131
|
+
def set(v); self.a = v; end
|
132
|
+
end
|
133
|
+
END
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should pass parameters correctly" do
|
137
|
+
obj = PrimitiveWithCustom.new(:iv => 5)
|
138
|
+
obj.value.should == 5
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe BinData::Primitive, "with custom mandatory parameters" do
|
143
|
+
before(:all) do
|
144
|
+
eval <<-END
|
145
|
+
class MandatoryPrimitive < BinData::Primitive
|
146
|
+
mandatory_parameter :arg1
|
147
|
+
|
148
|
+
uint8 :a, :value => :arg1
|
149
|
+
def get; self.a; end
|
150
|
+
def set(v); self.a = v; end
|
151
|
+
end
|
152
|
+
END
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should raise error if mandatory parameter is not supplied" do
|
156
|
+
lambda { MandatoryPrimitive.new }.should raise_error(ArgumentError)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should use mandatory parameter" do
|
160
|
+
obj = MandatoryPrimitive.new(:arg1 => 5)
|
161
|
+
obj.value.should == 5
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe BinData::Primitive, "with custom default parameters" do
|
166
|
+
before(:all) do
|
167
|
+
eval <<-END
|
168
|
+
class DefaultPrimitive < BinData::Primitive
|
169
|
+
default_parameter :arg1 => 5
|
170
|
+
|
171
|
+
uint8 :a, :value => :arg1
|
172
|
+
def get; self.a; end
|
173
|
+
def set(v); self.a = v; end
|
174
|
+
end
|
175
|
+
END
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should not raise error if default parameter is not supplied" do
|
179
|
+
lambda { DefaultPrimitive.new }.should_not raise_error(ArgumentError)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should use default parameter" do
|
183
|
+
obj = DefaultPrimitive.new
|
184
|
+
obj.value.should == 5
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should be able to override default parameter" do
|
188
|
+
obj = DefaultPrimitive.new(:arg1 => 7)
|
189
|
+
obj.value.should == 7
|
190
|
+
end
|
191
|
+
end
|