bindata 1.2.2 → 1.3.1
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 +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
data/spec/bits_spec.rb
CHANGED
@@ -4,31 +4,29 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
|
4
4
|
require 'bindata/bits'
|
5
5
|
|
6
6
|
describe "Bits of size 1" do
|
7
|
-
|
8
|
-
@bit_classes = [BinData::Bit1, BinData::Bit1le]
|
9
|
-
end
|
7
|
+
let(:bit_classes) { [BinData::Bit1, BinData::Bit1le] }
|
10
8
|
|
11
9
|
it "should accept true as value" do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
bit_classes.each do |bit_class|
|
11
|
+
subject = bit_class.new
|
12
|
+
subject.assign(true)
|
13
|
+
subject.should == 1
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
19
17
|
it "should accept false as value" do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
bit_classes.each do |bit_class|
|
19
|
+
subject = bit_class.new
|
20
|
+
subject.assign(false)
|
21
|
+
subject.should == 0
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
it "should accept nil as value" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
bit_classes.each do |bit_class|
|
27
|
+
subject = bit_class.new
|
28
|
+
subject.assign(nil)
|
29
|
+
subject.should == 0
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -37,35 +35,35 @@ share_examples_for "All bitfields" do
|
|
37
35
|
|
38
36
|
it "should have a sensible value of zero" do
|
39
37
|
all_classes do |bit_class|
|
40
|
-
bit_class.new.
|
38
|
+
bit_class.new.should be_zero
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
42
|
it "should avoid underflow" do
|
45
43
|
all_classes do |bit_class|
|
46
|
-
|
44
|
+
subject = bit_class.new
|
47
45
|
|
48
|
-
|
49
|
-
|
46
|
+
subject.assign(min_value - 1)
|
47
|
+
subject.should == min_value
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
51
|
it "should avoid overflow" do
|
54
52
|
all_classes do |bit_class|
|
55
|
-
|
53
|
+
subject = bit_class.new
|
56
54
|
|
57
|
-
|
58
|
-
|
55
|
+
subject.assign(max_value + 1)
|
56
|
+
subject.should == max_value
|
59
57
|
end
|
60
58
|
end
|
61
59
|
|
62
60
|
it "should assign values" do
|
63
61
|
all_classes do |bit_class|
|
64
62
|
some_values_within_range.each do |val|
|
65
|
-
|
66
|
-
|
63
|
+
subject = bit_class.new
|
64
|
+
subject.assign(val)
|
67
65
|
|
68
|
-
|
66
|
+
subject.should == val
|
69
67
|
end
|
70
68
|
end
|
71
69
|
end
|
@@ -73,13 +71,10 @@ share_examples_for "All bitfields" do
|
|
73
71
|
it "should assign values from other bit objects" do
|
74
72
|
all_classes do |bit_class|
|
75
73
|
some_values_within_range.each do |val|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
obj = bit_class.new
|
80
|
-
obj.assign(src)
|
74
|
+
subject = bit_class.new
|
75
|
+
subject.assign(bit_class.new(val))
|
81
76
|
|
82
|
-
|
77
|
+
subject.should == val
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
@@ -87,11 +82,10 @@ share_examples_for "All bitfields" do
|
|
87
82
|
it "should have symmetric #read and #write" do
|
88
83
|
all_classes do |bit_class|
|
89
84
|
some_values_within_range.each do |val|
|
90
|
-
|
91
|
-
|
85
|
+
subject = bit_class.new
|
86
|
+
subject.assign(val)
|
92
87
|
|
93
|
-
|
94
|
-
bit_class.read(written).should == val
|
88
|
+
subject.value_read_from_written.should == subject
|
95
89
|
end
|
96
90
|
end
|
97
91
|
end
|
@@ -124,25 +118,29 @@ share_examples_for "All bitfields" do
|
|
124
118
|
end
|
125
119
|
end
|
126
120
|
|
121
|
+
def generate_bit_classes_to_test(endian)
|
122
|
+
bits = {}
|
123
|
+
(1 .. 50).each do |nbits|
|
124
|
+
name = (endian == :big) ? "Bit#{nbits}" : "Bit#{nbits}le"
|
125
|
+
bit_class = BinData.const_get(name)
|
126
|
+
bits[bit_class] = nbits
|
127
|
+
end
|
128
|
+
bits
|
129
|
+
end
|
130
|
+
|
127
131
|
describe "Big endian bitfields" do
|
128
132
|
it_should_behave_like "All bitfields"
|
129
133
|
|
130
134
|
before(:all) do
|
131
|
-
@bits =
|
132
|
-
(1 .. 63).each do |nbits|
|
133
|
-
bit_class = BinData.const_get("Bit#{nbits}")
|
134
|
-
@bits[bit_class] = nbits
|
135
|
-
end
|
135
|
+
@bits = generate_bit_classes_to_test(:big)
|
136
136
|
end
|
137
137
|
|
138
138
|
it "should read big endian value" do
|
139
139
|
@bits.each_pair do |bit_class, nbits|
|
140
|
-
obj = bit_class.new
|
141
|
-
|
142
140
|
nbytes = (nbits + 7) / 8
|
143
141
|
str = [0b1000_0000].pack("C") + "\000" * (nbytes - 1)
|
144
|
-
|
145
|
-
|
142
|
+
|
143
|
+
bit_class.read(str).should == 1 << (nbits - 1)
|
146
144
|
end
|
147
145
|
end
|
148
146
|
end
|
@@ -151,21 +149,15 @@ describe "Little endian bitfields" do
|
|
151
149
|
it_should_behave_like "All bitfields"
|
152
150
|
|
153
151
|
before(:all) do
|
154
|
-
@bits =
|
155
|
-
(1 .. 63).each do |nbits|
|
156
|
-
bit_class = BinData.const_get("Bit#{nbits}le")
|
157
|
-
@bits[bit_class] = nbits
|
158
|
-
end
|
152
|
+
@bits = generate_bit_classes_to_test(:little)
|
159
153
|
end
|
160
154
|
|
161
155
|
it "should read little endian value" do
|
162
156
|
@bits.each_pair do |bit_class, nbits|
|
163
|
-
obj = bit_class.new
|
164
|
-
|
165
157
|
nbytes = (nbits + 7) / 8
|
166
158
|
str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
|
167
|
-
|
168
|
-
|
159
|
+
|
160
|
+
bit_class.read(str).should == 1
|
169
161
|
end
|
170
162
|
end
|
171
163
|
end
|
data/spec/choice_spec.rb
CHANGED
@@ -8,6 +8,23 @@ class Chooser
|
|
8
8
|
attr_accessor :choice
|
9
9
|
end
|
10
10
|
|
11
|
+
class BinData::Choice
|
12
|
+
def set_chooser(chooser)
|
13
|
+
@chooser = chooser
|
14
|
+
end
|
15
|
+
def choice=(s)
|
16
|
+
@chooser.choice = s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_choice(choices, options = {})
|
21
|
+
chooser = Chooser.new
|
22
|
+
params = {:choices => choices, :selection => lambda { chooser.choice } }.merge(options)
|
23
|
+
choice = BinData::Choice.new(params)
|
24
|
+
choice.set_chooser(chooser)
|
25
|
+
choice
|
26
|
+
end
|
27
|
+
|
11
28
|
describe BinData::Choice, "when instantiating" do
|
12
29
|
it "should ensure mandatory parameters are supplied" do
|
13
30
|
args = {}
|
@@ -41,170 +58,157 @@ end
|
|
41
58
|
|
42
59
|
share_examples_for "Choice initialized with array or hash" do
|
43
60
|
it "should be able to select the choice" do
|
44
|
-
|
45
|
-
|
61
|
+
subject.choice = 3
|
62
|
+
subject.should == 30
|
46
63
|
end
|
47
64
|
|
48
65
|
it "should show the current selection" do
|
49
|
-
|
50
|
-
|
66
|
+
subject.choice = 3
|
67
|
+
subject.selection.should == 3
|
51
68
|
end
|
52
69
|
|
53
70
|
it "should not be able to directly change the current selection" do
|
54
71
|
lambda {
|
55
|
-
|
72
|
+
subject.selection = 3
|
56
73
|
}.should raise_error(NoMethodError)
|
57
74
|
end
|
58
75
|
|
59
76
|
it "should forward #snapshot" do
|
60
|
-
|
61
|
-
|
77
|
+
subject.choice = 3
|
78
|
+
subject.snapshot.should == 30
|
62
79
|
end
|
63
80
|
|
64
81
|
it "should be able to change the choice" do
|
65
|
-
|
82
|
+
subject.choice = 3
|
66
83
|
|
67
|
-
|
68
|
-
|
84
|
+
subject.choice = 7
|
85
|
+
subject.should == 70
|
69
86
|
end
|
70
87
|
|
71
88
|
it "should fail if no choice has been set" do
|
72
|
-
lambda {
|
89
|
+
lambda { subject.to_s }.should raise_error(IndexError)
|
73
90
|
end
|
74
91
|
|
75
92
|
it "should not be able to select an invalid choice" do
|
76
|
-
|
77
|
-
lambda {
|
93
|
+
subject.choice = 99
|
94
|
+
lambda { subject.to_s }.should raise_error(IndexError)
|
78
95
|
end
|
79
96
|
|
80
97
|
it "should not be able to select a nil choice" do
|
81
|
-
|
82
|
-
lambda {
|
98
|
+
subject.choice = 1
|
99
|
+
lambda { subject.to_s }.should raise_error(IndexError)
|
83
100
|
end
|
84
101
|
|
85
102
|
it "should handle missing methods correctly" do
|
86
|
-
|
103
|
+
subject.choice = 3
|
87
104
|
|
88
|
-
|
89
|
-
|
90
|
-
lambda {
|
105
|
+
subject.should respond_to(:value)
|
106
|
+
subject.should_not respond_to(:does_not_exist)
|
107
|
+
lambda { subject.does_not_exist }.should raise_error(NoMethodError)
|
91
108
|
end
|
92
109
|
|
93
110
|
it "should delegate methods to the selected single choice" do
|
94
|
-
|
95
|
-
|
96
|
-
@data.num_bytes.should == ExampleSingle.new.num_bytes
|
111
|
+
subject.choice = 5
|
112
|
+
subject.num_bytes.should == ExampleSingle.new.num_bytes
|
97
113
|
end
|
98
114
|
end
|
99
115
|
|
100
116
|
describe BinData::Choice, "with sparse choices array" do
|
101
117
|
it_should_behave_like "Choice initialized with array or hash"
|
102
118
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
[:example_single, {:value => 70}]],
|
111
|
-
:selection => lambda { chooser.choice } )
|
112
|
-
@chooser = chooser
|
113
|
-
end
|
119
|
+
subject {
|
120
|
+
choices = [nil, nil, nil,
|
121
|
+
[:example_single, {:value => 30}], nil,
|
122
|
+
[:example_single, {:value => 50}], nil,
|
123
|
+
[:example_single, {:value => 70}]]
|
124
|
+
create_choice(choices)
|
125
|
+
}
|
114
126
|
end
|
115
127
|
|
116
128
|
describe BinData::Choice, "with choices hash" do
|
117
129
|
it_should_behave_like "Choice initialized with array or hash"
|
118
130
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@chooser = chooser
|
126
|
-
end
|
131
|
+
subject {
|
132
|
+
choices = {3 => [:example_single, {:value => 30}],
|
133
|
+
5 => [:example_single, {:value => 50}],
|
134
|
+
7 => [:example_single, {:value => 70}]}
|
135
|
+
create_choice(choices)
|
136
|
+
}
|
127
137
|
end
|
128
138
|
|
129
139
|
describe BinData::Choice, "with single values" do
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
@chooser = chooser
|
137
|
-
end
|
140
|
+
subject {
|
141
|
+
choices = {3 => :example_single,
|
142
|
+
5 => :example_single,
|
143
|
+
7 => :example_single}
|
144
|
+
create_choice(choices)
|
145
|
+
}
|
138
146
|
|
139
147
|
it "should assign raw values" do
|
140
|
-
|
141
|
-
|
142
|
-
|
148
|
+
subject.choice = 3
|
149
|
+
subject.assign(254)
|
150
|
+
subject.should == 254
|
143
151
|
end
|
144
152
|
|
145
153
|
it "should assign Single values" do
|
146
|
-
obj = ExampleSingle.new
|
147
|
-
obj.value = 11
|
154
|
+
obj = ExampleSingle.new(11)
|
148
155
|
|
149
|
-
|
150
|
-
|
151
|
-
|
156
|
+
subject.choice = 3
|
157
|
+
subject.assign(obj)
|
158
|
+
subject.should == 11
|
152
159
|
end
|
153
160
|
|
154
161
|
it "should clear" do
|
155
|
-
|
156
|
-
|
162
|
+
subject.choice = 3
|
163
|
+
subject.assign(254)
|
157
164
|
|
158
|
-
|
159
|
-
|
165
|
+
subject.clear
|
166
|
+
subject.should be_zero
|
160
167
|
end
|
161
168
|
|
162
169
|
it "should be clear on initialisation" do
|
163
|
-
|
170
|
+
subject.choice = 3
|
164
171
|
|
165
|
-
|
172
|
+
subject.should be_clear
|
166
173
|
end
|
167
174
|
|
168
175
|
it "should not be clear after assignment" do
|
169
|
-
|
170
|
-
|
176
|
+
subject.choice = 3
|
177
|
+
subject.assign(254)
|
171
178
|
|
172
|
-
|
179
|
+
subject.should_not be_clear
|
173
180
|
end
|
174
181
|
|
175
182
|
it "should not copy value when changing selection" do
|
176
|
-
|
177
|
-
|
183
|
+
subject.choice = 3
|
184
|
+
subject.assign(254)
|
178
185
|
|
179
|
-
|
180
|
-
|
186
|
+
subject.choice = 7
|
187
|
+
subject.should_not == 254
|
181
188
|
end
|
182
189
|
|
183
190
|
it "should behave as value" do
|
184
|
-
|
185
|
-
|
191
|
+
subject.choice = 3
|
192
|
+
subject.assign(5)
|
186
193
|
|
187
|
-
(
|
188
|
-
(1 +
|
194
|
+
(subject + 1).should == 6
|
195
|
+
(1 + subject).should == 6
|
189
196
|
end
|
190
197
|
end
|
191
198
|
|
192
199
|
describe BinData::Choice, "with copy_on_change => true" do
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
:copy_on_change => true)
|
200
|
-
@chooser = chooser
|
201
|
-
end
|
200
|
+
subject {
|
201
|
+
choices = {3 => :example_single,
|
202
|
+
5 => :example_single,
|
203
|
+
7 => :example_single}
|
204
|
+
create_choice(choices, :copy_on_change => true)
|
205
|
+
}
|
202
206
|
|
203
207
|
it "should copy value when changing selection" do
|
204
|
-
|
205
|
-
|
208
|
+
subject.choice = 3
|
209
|
+
subject.assign(254)
|
206
210
|
|
207
|
-
|
208
|
-
|
211
|
+
subject.choice = 7
|
212
|
+
subject.should == 254
|
209
213
|
end
|
210
214
|
end
|