bindata 0.9.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/bits_spec.rb
CHANGED
@@ -4,136 +4,164 @@ require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
|
4
4
|
require 'bindata/bits'
|
5
5
|
|
6
6
|
describe "Bits of size 1" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
obj.value.should == 1
|
7
|
+
before(:each) do
|
8
|
+
@bit_classes = [BinData::Bit1, BinData::Bit1le]
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
it "should accept true as value" do
|
12
|
+
@bit_classes.each do |bit_class|
|
13
|
+
obj = bit_class.new
|
14
|
+
obj.value = true
|
15
|
+
obj.value.should == 1
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should accept false as value" do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
obj.value = false
|
24
|
-
obj.value.should == 0
|
20
|
+
@bit_classes.each do |bit_class|
|
21
|
+
obj = bit_class.new
|
22
|
+
obj.value = false
|
23
|
+
obj.value.should == 0
|
24
|
+
end
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should accept nil as value" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
obj.value = nil
|
34
|
-
obj.value.should == 0
|
28
|
+
@bit_classes.each do |bit_class|
|
29
|
+
obj = bit_class.new
|
30
|
+
obj.value = nil
|
31
|
+
obj.value.should == 0
|
32
|
+
end
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
|
-
|
36
|
+
share_examples_for "All bitfields" do
|
37
|
+
|
39
38
|
it "should have a sensible value of zero" do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
39
|
+
all_classes do |bit_class|
|
40
|
+
bit_class.new.value.should be_zero
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should avoid underflow" do
|
45
|
+
all_classes do |bit_class|
|
46
|
+
obj = bit_class.new
|
47
|
+
|
48
|
+
obj.value = min_value - 1
|
49
|
+
obj.value.should == min_value
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
|
-
it "should
|
55
|
-
|
56
|
-
|
57
|
-
loop do
|
58
|
-
["", "le"].each do |suffix|
|
59
|
-
klass = BinData.const_get("Bit#{nbits}#{suffix}")
|
60
|
-
obj = klass.new
|
53
|
+
it "should avoid overflow" do
|
54
|
+
all_classes do |bit_class|
|
55
|
+
obj = bit_class.new
|
61
56
|
|
62
|
-
|
63
|
-
|
57
|
+
obj.value = max_value + 1
|
58
|
+
obj.value.should == max_value
|
59
|
+
end
|
60
|
+
end
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
it "should assign values" do
|
63
|
+
all_classes do |bit_class|
|
64
|
+
some_values_within_range.each do |val|
|
65
|
+
obj = bit_class.new
|
66
|
+
obj.assign(val)
|
68
67
|
|
69
|
-
|
68
|
+
obj.value.should == val
|
70
69
|
end
|
71
|
-
rescue NameError
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
|
-
it "should
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
obj = klass.new
|
73
|
+
it "should assign values from other bit objects" do
|
74
|
+
all_classes do |bit_class|
|
75
|
+
some_values_within_range.each do |val|
|
76
|
+
src = bit_class.new
|
77
|
+
src.assign(val)
|
81
78
|
|
82
|
-
|
83
|
-
obj.
|
84
|
-
obj.value.should == 1 << (nbits - 1)
|
79
|
+
obj = bit_class.new
|
80
|
+
obj.assign(src)
|
85
81
|
|
86
|
-
|
82
|
+
obj.value.should == val
|
87
83
|
end
|
88
|
-
rescue NameError
|
89
84
|
end
|
90
85
|
end
|
91
86
|
|
92
|
-
it "should read
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
obj = klass.new
|
98
|
-
|
99
|
-
str = [0b0000_0001].pack("C") + "\000" * (nbits / 8)
|
100
|
-
obj.read(str)
|
101
|
-
obj.value.should == 1
|
87
|
+
it "should have symmetric #read and #write" do
|
88
|
+
all_classes do |bit_class|
|
89
|
+
some_values_within_range.each do |val|
|
90
|
+
obj = bit_class.new
|
91
|
+
obj.value = val
|
102
92
|
|
103
|
-
|
93
|
+
written = obj.to_binary_s
|
94
|
+
bit_class.read(written).should == val
|
104
95
|
end
|
105
|
-
rescue NameError
|
106
96
|
end
|
107
97
|
end
|
108
98
|
|
109
|
-
|
110
|
-
|
111
|
-
nbits =
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
99
|
+
def all_classes(&block)
|
100
|
+
@bits.each_pair do |bit_class, nbits|
|
101
|
+
@nbits = nbits
|
102
|
+
yield bit_class
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def min_value
|
107
|
+
0
|
108
|
+
end
|
109
|
+
|
110
|
+
def max_value
|
111
|
+
(1 << @nbits) - 1
|
112
|
+
end
|
113
|
+
|
114
|
+
def some_values_within_range
|
115
|
+
lo = min_value + 1
|
116
|
+
mid = (min_value + max_value) / 2
|
117
|
+
hi = max_value - 1
|
118
|
+
|
119
|
+
[lo, mid, hi].find_all { |v| (min_value .. max_value).include?(v) }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "Big endian bitfields" do
|
124
|
+
it_should_behave_like "All bitfields"
|
125
|
+
|
126
|
+
before(:all) do
|
127
|
+
@bits = {}
|
128
|
+
(1 .. 63).each do |nbits|
|
129
|
+
bit_class = BinData.const_get("Bit#{nbits}")
|
130
|
+
@bits[bit_class] = nbits
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should read big endian value" do
|
135
|
+
@bits.each_pair do |bit_class, nbits|
|
136
|
+
obj = bit_class.new
|
137
|
+
|
138
|
+
nbytes = (nbits + 7) / 8
|
139
|
+
str = [0b1000_0000].pack("C") + "\000" * (nbytes - 1)
|
140
|
+
obj.read(str)
|
141
|
+
obj.value.should == 1 << (nbits - 1)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "Little endian bitfields" do
|
147
|
+
it_should_behave_like "All bitfields"
|
148
|
+
|
149
|
+
before(:all) do
|
150
|
+
@bits = {}
|
151
|
+
(1 .. 63).each do |nbits|
|
152
|
+
bit_class = BinData.const_get("Bit#{nbits}le")
|
153
|
+
@bits[bit_class] = nbits
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should read little endian value" do
|
158
|
+
@bits.each_pair do |bit_class, nbits|
|
159
|
+
obj = bit_class.new
|
160
|
+
|
161
|
+
nbytes = (nbits + 7) / 8
|
162
|
+
str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
|
163
|
+
obj.read(str)
|
164
|
+
obj.value.should == 1
|
137
165
|
end
|
138
166
|
end
|
139
167
|
end
|
data/spec/choice_spec.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require File.expand_path(File.dirname(__FILE__)) + '/example'
|
4
5
|
require 'bindata/choice'
|
5
|
-
require 'bindata/int'
|
6
|
-
require 'bindata/lazy'
|
7
|
-
require 'bindata/struct'
|
8
6
|
|
9
7
|
class Chooser
|
10
8
|
attr_accessor :choice
|
@@ -31,42 +29,35 @@ describe BinData::Choice, "when instantiating" do
|
|
31
29
|
end
|
32
30
|
|
33
31
|
it "should fail if :choices Hash has a symbol as key" do
|
34
|
-
args = {:choices => {:a => :
|
32
|
+
args = {:choices => {:a => :example_single}, :selection => 0}
|
35
33
|
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
36
34
|
end
|
37
35
|
|
38
36
|
it "should fail if :choices Hash has a nil key" do
|
39
|
-
args = {:choices => {nil => :
|
37
|
+
args = {:choices => {nil => :example_single}, :selection => 0}
|
40
38
|
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
chooser =
|
47
|
-
@data
|
48
|
-
[:int16le, {:value => 5}],
|
49
|
-
[:int32le, {:value => 7}]],
|
50
|
-
:selection => lambda { chooser.choice } )
|
51
|
-
@chooser = chooser
|
42
|
+
share_examples_for "Choice initialized with array or hash" do
|
43
|
+
it "should be able to select the choice" do
|
44
|
+
@chooser.choice = 3
|
45
|
+
@data.value.should == 30
|
52
46
|
end
|
53
47
|
|
54
|
-
it "should
|
55
|
-
@chooser.choice =
|
56
|
-
@data.selection.should ==
|
57
|
-
|
48
|
+
it "should show the current selection" do
|
49
|
+
@chooser.choice = 3
|
50
|
+
@data.selection.should == 3
|
51
|
+
end
|
58
52
|
|
59
|
-
|
60
|
-
@
|
61
|
-
@data.value.should == 5
|
53
|
+
it "should be able to change the choice" do
|
54
|
+
@chooser.choice = 3
|
62
55
|
|
63
|
-
@chooser.choice =
|
64
|
-
@data.
|
65
|
-
@data.value.should == 7
|
56
|
+
@chooser.choice = 7
|
57
|
+
@data.value.should == 70
|
66
58
|
end
|
67
59
|
|
68
|
-
it "should
|
69
|
-
@chooser.choice = nil
|
60
|
+
it "should fail if no choice has been set" do
|
70
61
|
lambda { @data.value }.should raise_error(IndexError)
|
71
62
|
end
|
72
63
|
|
@@ -75,8 +66,13 @@ describe BinData::Choice, "with choices array" do
|
|
75
66
|
lambda { @data.value }.should raise_error(IndexError)
|
76
67
|
end
|
77
68
|
|
69
|
+
it "should not be able to select a nil choice" do
|
70
|
+
@chooser.choice = 1
|
71
|
+
lambda { @data.value }.should raise_error(IndexError)
|
72
|
+
end
|
73
|
+
|
78
74
|
it "should handle missing methods correctly" do
|
79
|
-
@chooser.choice =
|
75
|
+
@chooser.choice = 3
|
80
76
|
|
81
77
|
@data.should respond_to(:value)
|
82
78
|
@data.should_not respond_to(:does_not_exist)
|
@@ -84,125 +80,120 @@ describe BinData::Choice, "with choices array" do
|
|
84
80
|
end
|
85
81
|
|
86
82
|
it "should delegate methods to the selected single choice" do
|
87
|
-
@chooser.choice =
|
83
|
+
@chooser.choice = 5
|
88
84
|
|
89
|
-
@data.num_bytes.should ==
|
85
|
+
@data.num_bytes.should == ExampleSingle.new.num_bytes
|
90
86
|
end
|
91
87
|
end
|
92
88
|
|
93
89
|
describe BinData::Choice, "with sparse choices array" do
|
90
|
+
it_should_behave_like "Choice initialized with array or hash"
|
91
|
+
|
94
92
|
before(:each) do
|
95
93
|
chooser = Chooser.new
|
96
94
|
@data = BinData::Choice.new(:choices => [nil, nil, nil,
|
97
|
-
[:
|
95
|
+
[:example_single, {:value => 30}],
|
98
96
|
nil,
|
99
|
-
[:
|
97
|
+
[:example_single, {:value => 50}],
|
100
98
|
nil,
|
101
|
-
[:
|
99
|
+
[:example_single, {:value => 70}]],
|
102
100
|
:selection => lambda { chooser.choice } )
|
103
101
|
@chooser = chooser
|
104
102
|
end
|
103
|
+
end
|
105
104
|
|
106
|
-
|
107
|
-
|
108
|
-
@data.selection.should == 3
|
109
|
-
@data.value.should == 3
|
110
|
-
|
111
|
-
@chooser.choice = 7
|
112
|
-
@data.selection.should == 7
|
113
|
-
@data.value.should == 7
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should not be able to select an invalid choice" do
|
117
|
-
@chooser.choice = 99
|
118
|
-
lambda { @data.value }.should raise_error(IndexError)
|
119
|
-
end
|
105
|
+
describe BinData::Choice, "with choices hash" do
|
106
|
+
it_should_behave_like "Choice initialized with array or hash"
|
120
107
|
|
121
|
-
|
122
|
-
|
123
|
-
|
108
|
+
before(:each) do
|
109
|
+
chooser = Chooser.new
|
110
|
+
@data = BinData::Choice.new(:choices => {3 => [:example_single, {:value => 30}],
|
111
|
+
5 => [:example_single, {:value => 50}],
|
112
|
+
7 => [:example_single, {:value => 70}]},
|
113
|
+
:selection => lambda { chooser.choice } )
|
114
|
+
@chooser = chooser
|
124
115
|
end
|
125
116
|
end
|
126
117
|
|
127
|
-
describe BinData::Choice, "with
|
118
|
+
describe BinData::Choice, "with single values" do
|
128
119
|
before(:each) do
|
129
120
|
chooser = Chooser.new
|
130
|
-
@data = BinData::Choice.new(:choices => {3 =>
|
131
|
-
5 =>
|
132
|
-
7 =>
|
121
|
+
@data = BinData::Choice.new(:choices => {3 => :example_single,
|
122
|
+
5 => :example_single,
|
123
|
+
7 => :example_single,},
|
133
124
|
:selection => lambda { chooser.choice } )
|
134
125
|
@chooser = chooser
|
135
126
|
end
|
136
127
|
|
137
|
-
it "should
|
128
|
+
it "should assign raw values" do
|
138
129
|
@chooser.choice = 3
|
139
|
-
@data.value
|
140
|
-
@data.
|
130
|
+
@data.value = 254
|
131
|
+
@data.value.should == 254
|
132
|
+
end
|
141
133
|
|
142
|
-
|
143
|
-
|
144
|
-
|
134
|
+
it "should assign Single values" do
|
135
|
+
obj = ExampleSingle.new
|
136
|
+
obj.value = 11
|
137
|
+
|
138
|
+
@chooser.choice = 3
|
139
|
+
@data.value = obj
|
140
|
+
@data.value.should == 11
|
145
141
|
end
|
146
142
|
|
147
|
-
it "should
|
148
|
-
@chooser.choice =
|
149
|
-
|
143
|
+
it "should clear" do
|
144
|
+
@chooser.choice = 3
|
145
|
+
@data.value = 254
|
146
|
+
|
147
|
+
@data.clear
|
148
|
+
@data.value.should be_zero
|
150
149
|
end
|
151
|
-
end
|
152
150
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
@data
|
157
|
-
5 => :uint16le,
|
158
|
-
7 => :uint32le,},
|
159
|
-
:selection => lambda { chooser.choice } )
|
160
|
-
@chooser = chooser
|
151
|
+
it "should be clear on initialisation" do
|
152
|
+
@chooser.choice = 3
|
153
|
+
|
154
|
+
@data.should be_clear
|
161
155
|
end
|
162
156
|
|
163
|
-
it "should
|
157
|
+
it "should not be clear after assignment" do
|
164
158
|
@chooser.choice = 3
|
165
159
|
@data.value = 254
|
166
160
|
|
167
|
-
@data.
|
161
|
+
@data.should_not be_clear
|
162
|
+
end
|
168
163
|
|
169
|
-
|
170
|
-
@
|
164
|
+
it "should not copy value when changing selection" do
|
165
|
+
@chooser.choice = 3
|
166
|
+
@data.value = 254
|
171
167
|
|
172
168
|
@chooser.choice = 7
|
173
|
-
@data.
|
169
|
+
@data.value.should_not == 254
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should behave as value" do
|
173
|
+
@chooser.choice = 3
|
174
|
+
@data.value = 5
|
175
|
+
|
176
|
+
(@data + 1).should == 6
|
177
|
+
(1 + @data).should == 6
|
174
178
|
end
|
175
179
|
end
|
176
180
|
|
177
|
-
describe BinData::Choice, "with
|
181
|
+
describe BinData::Choice, "with copy_on_change => true" do
|
178
182
|
before(:each) do
|
179
183
|
chooser = Chooser.new
|
180
|
-
@data = BinData::Choice.new(:choices =>
|
181
|
-
|
182
|
-
|
183
|
-
:selection => lambda { chooser.choice }
|
184
|
+
@data = BinData::Choice.new(:choices => {3 => :example_single,
|
185
|
+
5 => :example_single,
|
186
|
+
7 => :example_single,},
|
187
|
+
:selection => lambda { chooser.choice },
|
188
|
+
:copy_on_change => true)
|
184
189
|
@chooser = chooser
|
185
190
|
end
|
186
191
|
|
187
|
-
it "should
|
188
|
-
@chooser.choice = 3
|
189
|
-
@data.a = 5
|
190
|
-
@data.a.should == 5
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should not copy values when changing fields" do
|
194
|
-
@chooser.choice = 3
|
195
|
-
@data.a = 5
|
196
|
-
@data.a.should == 5
|
197
|
-
|
198
|
-
@chooser.choice = 5
|
199
|
-
@data.a = 17
|
200
|
-
@data.a.should == 17
|
201
|
-
|
192
|
+
it "should copy value when changing selection" do
|
202
193
|
@chooser.choice = 3
|
203
|
-
@data.
|
194
|
+
@data.value = 254
|
204
195
|
|
205
|
-
@chooser.choice =
|
206
|
-
@data.
|
196
|
+
@chooser.choice = 7
|
197
|
+
@data.value.should == 254
|
207
198
|
end
|
208
199
|
end
|