jbangert-bindata 1.5.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.
- data/.gitignore +1 -0
- data/BSDL +22 -0
- data/COPYING +52 -0
- data/ChangeLog.rdoc +204 -0
- data/Gemfile +2 -0
- data/INSTALL +11 -0
- data/NEWS.rdoc +164 -0
- data/README.md +54 -0
- data/Rakefile +13 -0
- data/bindata.gemspec +31 -0
- data/doc/manual.haml +407 -0
- data/doc/manual.md +1649 -0
- data/examples/NBT.txt +149 -0
- data/examples/gzip.rb +161 -0
- data/examples/ip_address.rb +22 -0
- data/examples/list.rb +124 -0
- data/examples/nbt.rb +178 -0
- data/lib/bindata.rb +33 -0
- data/lib/bindata/alignment.rb +83 -0
- data/lib/bindata/array.rb +335 -0
- data/lib/bindata/base.rb +388 -0
- data/lib/bindata/base_primitive.rb +214 -0
- data/lib/bindata/bits.rb +87 -0
- data/lib/bindata/choice.rb +216 -0
- data/lib/bindata/count_bytes_remaining.rb +35 -0
- data/lib/bindata/deprecated.rb +50 -0
- data/lib/bindata/dsl.rb +312 -0
- data/lib/bindata/float.rb +80 -0
- data/lib/bindata/int.rb +184 -0
- data/lib/bindata/io.rb +274 -0
- data/lib/bindata/lazy.rb +105 -0
- data/lib/bindata/offset.rb +91 -0
- data/lib/bindata/params.rb +135 -0
- data/lib/bindata/primitive.rb +135 -0
- data/lib/bindata/record.rb +110 -0
- data/lib/bindata/registry.rb +92 -0
- data/lib/bindata/rest.rb +35 -0
- data/lib/bindata/sanitize.rb +290 -0
- data/lib/bindata/skip.rb +48 -0
- data/lib/bindata/string.rb +145 -0
- data/lib/bindata/stringz.rb +96 -0
- data/lib/bindata/struct.rb +388 -0
- data/lib/bindata/trace.rb +94 -0
- data/lib/bindata/version.rb +3 -0
- data/setup.rb +1585 -0
- data/spec/alignment_spec.rb +61 -0
- data/spec/array_spec.rb +331 -0
- data/spec/base_primitive_spec.rb +238 -0
- data/spec/base_spec.rb +376 -0
- data/spec/bits_spec.rb +163 -0
- data/spec/choice_spec.rb +263 -0
- data/spec/count_bytes_remaining_spec.rb +38 -0
- data/spec/deprecated_spec.rb +31 -0
- data/spec/example.rb +21 -0
- data/spec/float_spec.rb +37 -0
- data/spec/int_spec.rb +216 -0
- data/spec/io_spec.rb +352 -0
- data/spec/lazy_spec.rb +217 -0
- data/spec/primitive_spec.rb +202 -0
- data/spec/record_spec.rb +530 -0
- data/spec/registry_spec.rb +108 -0
- data/spec/rest_spec.rb +26 -0
- data/spec/skip_spec.rb +27 -0
- data/spec/spec_common.rb +58 -0
- data/spec/string_spec.rb +300 -0
- data/spec/stringz_spec.rb +118 -0
- data/spec/struct_spec.rb +350 -0
- data/spec/system_spec.rb +380 -0
- data/tasks/manual.rake +36 -0
- data/tasks/rspec.rake +17 -0
- metadata +208 -0
data/spec/choice_spec.rb
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "example"))
|
5
|
+
require 'bindata/choice'
|
6
|
+
require 'bindata/int'
|
7
|
+
|
8
|
+
class Chooser
|
9
|
+
attr_accessor :choice
|
10
|
+
end
|
11
|
+
|
12
|
+
class BinData::Choice
|
13
|
+
def set_chooser(chooser)
|
14
|
+
@chooser = chooser
|
15
|
+
end
|
16
|
+
def choice=(s)
|
17
|
+
@chooser.choice = s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_choice(choices, options = {})
|
22
|
+
chooser = Chooser.new
|
23
|
+
params = {:choices => choices, :selection => lambda { chooser.choice } }.merge(options)
|
24
|
+
choice = BinData::Choice.new(params)
|
25
|
+
choice.set_chooser(chooser)
|
26
|
+
choice
|
27
|
+
end
|
28
|
+
|
29
|
+
describe BinData::Choice, "when instantiating" do
|
30
|
+
it "ensures mandatory parameters are supplied" do
|
31
|
+
args = {}
|
32
|
+
expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
|
33
|
+
|
34
|
+
args = {:selection => 1}
|
35
|
+
expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
|
36
|
+
|
37
|
+
args = {:choices => []}
|
38
|
+
expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "fails when a given type is unknown" do
|
42
|
+
args = {:choices => [:does_not_exist], :selection => 0}
|
43
|
+
expect { BinData::Choice.new(args) }.to raise_error(BinData::UnRegisteredTypeError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "fails when a given type is unknown" do
|
47
|
+
args = {:choices => {0 => :does_not_exist}, :selection => 0}
|
48
|
+
expect { BinData::Choice.new(args) }.to raise_error(BinData::UnRegisteredTypeError)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "fails when :choices Hash has a symbol as key" do
|
52
|
+
args = {:choices => {:a => :example_single}, :selection => 0}
|
53
|
+
expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "fails when :choices Hash has a nil key" do
|
57
|
+
args = {:choices => {nil => :example_single}, :selection => 0}
|
58
|
+
expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
shared_examples "Choice initialized with array or hash" do
|
63
|
+
it "can select the choice" do
|
64
|
+
subject.choice = 3
|
65
|
+
subject.should == 30
|
66
|
+
end
|
67
|
+
|
68
|
+
it "shows the current selection" do
|
69
|
+
subject.choice = 3
|
70
|
+
subject.selection.should == 3
|
71
|
+
end
|
72
|
+
|
73
|
+
it "forwards #snapshot" do
|
74
|
+
subject.choice = 3
|
75
|
+
subject.snapshot.should == 30
|
76
|
+
end
|
77
|
+
|
78
|
+
it "can change the choice" do
|
79
|
+
subject.choice = 3
|
80
|
+
|
81
|
+
subject.choice = 7
|
82
|
+
subject.should == 70
|
83
|
+
end
|
84
|
+
|
85
|
+
it "fails if no choice has been set" do
|
86
|
+
expect { subject.to_s }.to raise_error(IndexError)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "will not select an invalid choice" do
|
90
|
+
subject.choice = 99
|
91
|
+
expect { subject.to_s }.to raise_error(IndexError)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "will not select a nil choice" do
|
95
|
+
subject.choice = 1
|
96
|
+
expect { subject.to_s }.to raise_error(IndexError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "handles missing methods correctly" do
|
100
|
+
subject.choice = 3
|
101
|
+
|
102
|
+
subject.should respond_to(:value)
|
103
|
+
subject.should_not respond_to(:does_not_exist)
|
104
|
+
expect { subject.does_not_exist }.to raise_error(NoMethodError)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "delegates methods to the selected single choice" do
|
108
|
+
subject.choice = 5
|
109
|
+
subject.num_bytes.should == ExampleSingle.new.num_bytes
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe BinData::Choice, "with sparse choices array" do
|
114
|
+
include_examples "Choice initialized with array or hash"
|
115
|
+
|
116
|
+
subject {
|
117
|
+
choices = [nil, nil, nil,
|
118
|
+
[:example_single, {:value => 30}], nil,
|
119
|
+
[:example_single, {:value => 50}], nil,
|
120
|
+
[:example_single, {:value => 70}]]
|
121
|
+
create_choice(choices)
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
describe BinData::Choice, "with choices hash" do
|
126
|
+
include_examples "Choice initialized with array or hash"
|
127
|
+
|
128
|
+
subject {
|
129
|
+
choices = {3 => [:example_single, {:value => 30}],
|
130
|
+
5 => [:example_single, {:value => 50}],
|
131
|
+
7 => [:example_single, {:value => 70}]}
|
132
|
+
create_choice(choices)
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
describe BinData::Choice, "with single values" do
|
137
|
+
subject {
|
138
|
+
choices = {3 => :example_single,
|
139
|
+
5 => :example_single,
|
140
|
+
7 => :example_single}
|
141
|
+
create_choice(choices)
|
142
|
+
}
|
143
|
+
|
144
|
+
it "assigns raw values" do
|
145
|
+
subject.choice = 3
|
146
|
+
subject.assign(254)
|
147
|
+
subject.should == 254
|
148
|
+
end
|
149
|
+
|
150
|
+
it "assigns Single values" do
|
151
|
+
obj = ExampleSingle.new(11)
|
152
|
+
|
153
|
+
subject.choice = 3
|
154
|
+
subject.assign(obj)
|
155
|
+
subject.should == 11
|
156
|
+
end
|
157
|
+
|
158
|
+
it "clears" do
|
159
|
+
subject.choice = 3
|
160
|
+
subject.assign(254)
|
161
|
+
|
162
|
+
subject.clear
|
163
|
+
subject.should be_zero
|
164
|
+
end
|
165
|
+
|
166
|
+
it "clears all possible choices" do
|
167
|
+
subject.choice = 3
|
168
|
+
subject.assign(10)
|
169
|
+
subject.choice = 5
|
170
|
+
subject.assign(11)
|
171
|
+
|
172
|
+
subject.clear
|
173
|
+
|
174
|
+
subject.choice = 3
|
175
|
+
subject.should be_zero
|
176
|
+
end
|
177
|
+
|
178
|
+
it "is clear on initialisation" do
|
179
|
+
subject.choice = 3
|
180
|
+
|
181
|
+
subject.should be_clear
|
182
|
+
end
|
183
|
+
|
184
|
+
it "is not clear after assignment" do
|
185
|
+
subject.choice = 3
|
186
|
+
subject.assign(254)
|
187
|
+
|
188
|
+
subject.should_not be_clear
|
189
|
+
end
|
190
|
+
|
191
|
+
it "does not copy value when changing selection" do
|
192
|
+
subject.choice = 3
|
193
|
+
subject.assign(254)
|
194
|
+
|
195
|
+
subject.choice = 7
|
196
|
+
subject.should_not == 254
|
197
|
+
end
|
198
|
+
|
199
|
+
it "behaves as value" do
|
200
|
+
subject.choice = 3
|
201
|
+
subject.assign(5)
|
202
|
+
|
203
|
+
(subject + 1).should == 6
|
204
|
+
(1 + subject).should == 6
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe BinData::Choice, "with copy_on_change => true" do
|
209
|
+
subject {
|
210
|
+
choices = {3 => :example_single,
|
211
|
+
5 => :example_single,
|
212
|
+
7 => :example_single}
|
213
|
+
create_choice(choices, :copy_on_change => true)
|
214
|
+
}
|
215
|
+
|
216
|
+
it "copies value when changing selection" do
|
217
|
+
subject.choice = 3
|
218
|
+
subject.assign(254)
|
219
|
+
|
220
|
+
subject.choice = 7
|
221
|
+
subject.should == 254
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe BinData::Choice, "with :default" do
|
226
|
+
let(:choices) { { "a" => :int8, :default => :int16be } }
|
227
|
+
|
228
|
+
it "selects for existing case" do
|
229
|
+
subject = BinData::Choice.new(:selection => "a", :choices => choices)
|
230
|
+
subject.num_bytes.should == 1
|
231
|
+
end
|
232
|
+
|
233
|
+
it "selects for default case" do
|
234
|
+
subject = BinData::Choice.new(:selection => "other", :choices => choices)
|
235
|
+
subject.num_bytes.should == 2
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe BinData::Choice, "subclassed with default parameters" do
|
240
|
+
class DerivedChoice < BinData::Choice
|
241
|
+
endian :big
|
242
|
+
default_parameter :selection => 'a'
|
243
|
+
|
244
|
+
uint16 'a'
|
245
|
+
uint32 'b'
|
246
|
+
uint64 :default
|
247
|
+
end
|
248
|
+
|
249
|
+
it "sets initial selection" do
|
250
|
+
subject = DerivedChoice.new
|
251
|
+
subject.num_bytes.should == 2
|
252
|
+
end
|
253
|
+
|
254
|
+
it "overides default parameter" do
|
255
|
+
subject = DerivedChoice.new(:selection => 'b')
|
256
|
+
subject.num_bytes.should == 4
|
257
|
+
end
|
258
|
+
|
259
|
+
it "selects default selection" do
|
260
|
+
subject = DerivedChoice.new(:selection => 'z')
|
261
|
+
subject.num_bytes.should == 8
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/count_bytes_remaining'
|
5
|
+
|
6
|
+
describe BinData::CountBytesRemaining do
|
7
|
+
it { should == 0 }
|
8
|
+
its(:num_bytes) { should be_zero }
|
9
|
+
|
10
|
+
it "counts till end of stream" do
|
11
|
+
data = "abcdefghij"
|
12
|
+
subject.read(data).should == 10
|
13
|
+
end
|
14
|
+
|
15
|
+
it "does not read any data" do
|
16
|
+
io = StringIO.new "abcdefghij"
|
17
|
+
subject.read(io)
|
18
|
+
|
19
|
+
io.pos.should == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it "does not write any data" do
|
23
|
+
subject.to_binary_s.should == ""
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows setting value for completeness" do
|
27
|
+
subject.assign("123")
|
28
|
+
subject.should == "123"
|
29
|
+
subject.to_binary_s.should == ""
|
30
|
+
end
|
31
|
+
|
32
|
+
it "accepts BinData::BasePrimitive parameters" do
|
33
|
+
count = BinData::CountBytesRemaining.new(:check_value => 2)
|
34
|
+
expect {
|
35
|
+
count.read("xyz")
|
36
|
+
}.to raise_error(BinData::ValidityError)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "example"))
|
5
|
+
require 'bindata'
|
6
|
+
|
7
|
+
describe BinData::Base, "when defining" do
|
8
|
+
it "fails if #initialize is overridden" do
|
9
|
+
class BaseWithInitialize < BinData::Base
|
10
|
+
def initialize(params = {}, parent = nil)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
expect {
|
16
|
+
BaseWithInitialize.new
|
17
|
+
}.to raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
it "handles if #initialize is naively renamed to #initialize_instance" do
|
21
|
+
class BaseWithInitializeInstance < BinData::Base
|
22
|
+
def initialize_instance(params = {}, parent = nil)
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
expect {
|
28
|
+
BaseWithInitializeInstance.new
|
29
|
+
}.to raise_error
|
30
|
+
end
|
31
|
+
end
|
data/spec/example.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bindata/base_primitive'
|
2
|
+
|
3
|
+
class ExampleSingle < BinData::BasePrimitive
|
4
|
+
def self.io_with_value(val)
|
5
|
+
BinData::IO.new([val].pack("V"))
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def value_to_binary_string(val)
|
11
|
+
[val].pack("V")
|
12
|
+
end
|
13
|
+
|
14
|
+
def read_and_return_value(io)
|
15
|
+
io.readbytes(4).unpack("V").at(0)
|
16
|
+
end
|
17
|
+
|
18
|
+
def sensible_default
|
19
|
+
0
|
20
|
+
end
|
21
|
+
end
|
data/spec/float_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/float'
|
5
|
+
|
6
|
+
describe "A FloatLe" do
|
7
|
+
subject { BinData::FloatLe.new(Math::PI) }
|
8
|
+
|
9
|
+
its(:num_bytes) { should == 4 }
|
10
|
+
its(:to_binary_s) { should == [Math::PI].pack('e') }
|
11
|
+
its(:value_read_from_written) { should be_within(0.000001).of(Math::PI) }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "A FloatBe" do
|
15
|
+
subject { BinData::FloatBe.new(Math::PI) }
|
16
|
+
|
17
|
+
its(:num_bytes) { should == 4 }
|
18
|
+
its(:to_binary_s) { should == [Math::PI].pack('g') }
|
19
|
+
its(:value_read_from_written) { should be_within(0.000001).of(Math::PI) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "A DoubleLe" do
|
23
|
+
subject { BinData::DoubleLe.new(Math::PI) }
|
24
|
+
|
25
|
+
its(:num_bytes) { should == 8 }
|
26
|
+
its(:to_binary_s) { should == [Math::PI].pack('E') }
|
27
|
+
its(:value_read_from_written) { should be_within(0.0000000000000001).of(Math::PI) }
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe "A DoubleBe" do
|
32
|
+
subject { BinData::DoubleBe.new(Math::PI) }
|
33
|
+
|
34
|
+
its(:num_bytes) { should == 8 }
|
35
|
+
its(:to_binary_s) { should == [Math::PI].pack('G') }
|
36
|
+
its(:value_read_from_written) { should be_within(0.0000000000000001).of(Math::PI) }
|
37
|
+
end
|
data/spec/int_spec.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata'
|
5
|
+
|
6
|
+
shared_examples "All Integers" do
|
7
|
+
|
8
|
+
it "have correct num_bytes" do
|
9
|
+
all_classes do |int_class|
|
10
|
+
int_class.new.num_bytes.should == @nbytes
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "have a sensible value of zero" do
|
15
|
+
all_classes do |int_class|
|
16
|
+
int_class.new.should be_zero
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "avoid underflow" do
|
21
|
+
all_classes do |int_class|
|
22
|
+
subject = int_class.new
|
23
|
+
subject.assign(min_value - 1)
|
24
|
+
|
25
|
+
subject.should == min_value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "avoid overflow" do
|
30
|
+
all_classes do |int_class|
|
31
|
+
subject = int_class.new
|
32
|
+
subject.assign(max_value + 1)
|
33
|
+
|
34
|
+
subject.should == max_value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "assign values" do
|
39
|
+
all_classes do |int_class|
|
40
|
+
subject = int_class.new
|
41
|
+
test_int = gen_test_int
|
42
|
+
subject.assign(test_int)
|
43
|
+
|
44
|
+
subject.should == test_int
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "assign values from other int objects" do
|
49
|
+
all_classes do |int_class|
|
50
|
+
src = int_class.new
|
51
|
+
src.assign(gen_test_int)
|
52
|
+
|
53
|
+
subject = int_class.new
|
54
|
+
subject.assign(src)
|
55
|
+
subject.should == src
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "symmetrically read and write a +ve number" do
|
60
|
+
all_classes do |int_class|
|
61
|
+
subject = int_class.new
|
62
|
+
subject.assign(gen_test_int)
|
63
|
+
|
64
|
+
subject.value_read_from_written.should == subject
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "symmetrically read and write a -ve number" do
|
69
|
+
all_classes do |int_class|
|
70
|
+
if @signed
|
71
|
+
subject = int_class.new
|
72
|
+
subject.assign(-gen_test_int)
|
73
|
+
|
74
|
+
subject.value_read_from_written.should == subject
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "convert a +ve number to string" do
|
80
|
+
all_classes do |int_class|
|
81
|
+
val = gen_test_int
|
82
|
+
|
83
|
+
subject = int_class.new
|
84
|
+
subject.assign(val)
|
85
|
+
|
86
|
+
subject.to_binary_s.should == int_to_binary_str(val)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "convert a -ve number to string" do
|
91
|
+
all_classes do |int_class|
|
92
|
+
if @signed
|
93
|
+
val = -gen_test_int
|
94
|
+
|
95
|
+
subject = int_class.new
|
96
|
+
subject.assign(val)
|
97
|
+
|
98
|
+
subject.to_binary_s.should == int_to_binary_str(val)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def all_classes(&block)
|
104
|
+
@ints.each_pair do |int_class, nbytes|
|
105
|
+
@nbytes = nbytes
|
106
|
+
yield int_class
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def min_value
|
111
|
+
if @signed
|
112
|
+
-max_value - 1
|
113
|
+
else
|
114
|
+
0
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def max_value
|
119
|
+
if @signed
|
120
|
+
(1 << (@nbytes * 8 - 1)) - 1
|
121
|
+
else
|
122
|
+
(1 << (@nbytes * 8)) - 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def gen_test_int
|
127
|
+
# resulting int is guaranteed to be +ve for signed or unsigned integers
|
128
|
+
(0 ... @nbytes).inject(0) { |val, i| (val << 8) | ((val + 0x11) % 0x100) }
|
129
|
+
end
|
130
|
+
|
131
|
+
def int_to_binary_str(val)
|
132
|
+
str = binary("")
|
133
|
+
v = val & ((1 << (@nbytes * 8)) - 1)
|
134
|
+
@nbytes.times do
|
135
|
+
str.concat(v & 0xff)
|
136
|
+
v >>= 8
|
137
|
+
end
|
138
|
+
(@endian == :little) ? str : str.reverse
|
139
|
+
end
|
140
|
+
|
141
|
+
def create_mapping_of_class_to_nbits(endian, signed)
|
142
|
+
base = signed ? "Int" : "Uint"
|
143
|
+
signed_sym = signed ? :signed : :unsigned
|
144
|
+
endian_str = (endian == :little) ? "le" : "be"
|
145
|
+
|
146
|
+
result = {}
|
147
|
+
result[BinData.const_get("#{base}8")] = 1
|
148
|
+
(1 .. 20).each do |nbytes|
|
149
|
+
nbits = nbytes * 8
|
150
|
+
class_name = "#{base}#{nbits}#{endian_str}"
|
151
|
+
result[BinData.const_get(class_name)] = nbytes
|
152
|
+
end
|
153
|
+
|
154
|
+
result
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "All signed big endian integers" do
|
159
|
+
include_examples "All Integers"
|
160
|
+
|
161
|
+
before(:all) do
|
162
|
+
@endian = :big
|
163
|
+
@signed = true
|
164
|
+
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "All unsigned big endian integers" do
|
169
|
+
include_examples "All Integers"
|
170
|
+
|
171
|
+
before(:all) do
|
172
|
+
@endian = :big
|
173
|
+
@signed = false
|
174
|
+
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "All signed little endian integers" do
|
179
|
+
include_examples "All Integers"
|
180
|
+
|
181
|
+
before(:all) do
|
182
|
+
@endian = :little
|
183
|
+
@signed = true
|
184
|
+
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "All unsigned little endian integers" do
|
189
|
+
include_examples "All Integers"
|
190
|
+
|
191
|
+
before(:all) do
|
192
|
+
@endian = :little
|
193
|
+
@signed = false
|
194
|
+
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "Custom defined integers" do
|
199
|
+
it "fail unless bits are a multiple of 8" do
|
200
|
+
expect {
|
201
|
+
BinData::Uint7le
|
202
|
+
}.to raise_error
|
203
|
+
|
204
|
+
expect {
|
205
|
+
BinData::Uint7be
|
206
|
+
}.to raise_error
|
207
|
+
|
208
|
+
expect {
|
209
|
+
BinData::Int7le
|
210
|
+
}.to raise_error
|
211
|
+
|
212
|
+
expect {
|
213
|
+
BinData::Int7be
|
214
|
+
}.to raise_error
|
215
|
+
end
|
216
|
+
end
|