bindata 0.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.
Potentially problematic release.
This version of bindata might be problematic. Click here for more details.
- data/COPYING +52 -0
- data/ChangeLog +9 -0
- data/GPL +339 -0
- data/INSTALL +7 -0
- data/README +215 -0
- data/TODO +14 -0
- data/examples/gzip.rb +174 -0
- data/lib/bindata.rb +13 -0
- data/lib/bindata/array.rb +160 -0
- data/lib/bindata/base.rb +260 -0
- data/lib/bindata/choice.rb +120 -0
- data/lib/bindata/int.rb +171 -0
- data/lib/bindata/lazy.rb +71 -0
- data/lib/bindata/registry.rb +37 -0
- data/lib/bindata/single.rb +170 -0
- data/lib/bindata/string.rb +98 -0
- data/lib/bindata/stringz.rb +83 -0
- data/lib/bindata/struct.rb +292 -0
- data/spec/array_spec.rb +121 -0
- data/spec/base_spec.rb +194 -0
- data/spec/choice_spec.rb +105 -0
- data/spec/int_spec.rb +141 -0
- data/spec/lazy_spec.rb +120 -0
- data/spec/registry_spec.rb +47 -0
- data/spec/single_spec.rb +210 -0
- data/spec/spec_common.rb +10 -0
- data/spec/string_spec.rb +205 -0
- data/spec/stringz_spec.rb +159 -0
- data/spec/struct_spec.rb +190 -0
- metadata +78 -0
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require 'bindata/array'
|
5
|
+
require 'bindata/int'
|
6
|
+
require 'bindata/struct'
|
7
|
+
|
8
|
+
context "Instantiating an Array" do
|
9
|
+
specify "should ensure mandatory parameters are supplied" do
|
10
|
+
args = {}
|
11
|
+
lambda { BinData::Array.new(args) }.should raise_error(ArgumentError)
|
12
|
+
args = {:type => :int8}
|
13
|
+
lambda { BinData::Array.new(args) }.should raise_error(ArgumentError)
|
14
|
+
args = {:initial_length => 3}
|
15
|
+
lambda { BinData::Array.new(args) }.should raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should fail if a given type is unknown" do
|
19
|
+
args = {:type => :does_not_exist, :initial_length => 3}
|
20
|
+
lambda { BinData::Array.new(args) }.should raise_error(TypeError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "An Array with several elements" do
|
25
|
+
setup do
|
26
|
+
type = [:int16le, {:initial_value => lambda { index + 1 }}]
|
27
|
+
@data = BinData::Array.new(:type => type, :initial_length => 5)
|
28
|
+
end
|
29
|
+
|
30
|
+
specify "should return a correct snapshot" do
|
31
|
+
@data.snapshot.should == [1, 2, 3, 4, 5]
|
32
|
+
end
|
33
|
+
|
34
|
+
specify "should have correct num elements" do
|
35
|
+
@data.length.should == 5
|
36
|
+
@data.size.should == 5
|
37
|
+
end
|
38
|
+
|
39
|
+
specify "should have correct num_bytes" do
|
40
|
+
@data.num_bytes.should == 10
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "should have correct num_bytes for individual elements" do
|
44
|
+
@data.num_bytes(0).should == 2
|
45
|
+
end
|
46
|
+
|
47
|
+
specify "should have no field_names" do
|
48
|
+
@data.field_names.should be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should be able to directly access elements" do
|
52
|
+
@data[1] = 8
|
53
|
+
@data[1].should == 8
|
54
|
+
end
|
55
|
+
|
56
|
+
specify "should be able to use methods from Enumerable" do
|
57
|
+
@data.select { |x| (x % 2) == 0 }.should == [2, 4]
|
58
|
+
end
|
59
|
+
|
60
|
+
specify "should clear" do
|
61
|
+
@data[1] = 8
|
62
|
+
@data.clear
|
63
|
+
@data.collect.should == [1, 2, 3, 4, 5]
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should clear a single element" do
|
67
|
+
@data[1] = 8
|
68
|
+
@data.clear(1)
|
69
|
+
@data[1].should == 2
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should be clear upon creation" do
|
73
|
+
@data.clear?.should be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
specify "should be clear if all elements are clear" do
|
77
|
+
@data[1] = 8
|
78
|
+
@data.clear(1)
|
79
|
+
@data.clear?.should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
specify "should test clear status of individual elements" do
|
83
|
+
@data[1] = 8
|
84
|
+
@data.clear?(0).should be_true
|
85
|
+
@data.clear?(1).should be_false
|
86
|
+
end
|
87
|
+
|
88
|
+
specify "should read and write correctly" do
|
89
|
+
io = StringIO.new
|
90
|
+
@data[1] = 8
|
91
|
+
@data.write(io)
|
92
|
+
|
93
|
+
@data.clear
|
94
|
+
io.rewind
|
95
|
+
@data[1].should == 2
|
96
|
+
|
97
|
+
@data.read(io)
|
98
|
+
@data[1].should == 8
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "An Array containing structs" do
|
103
|
+
setup do
|
104
|
+
type = [:struct, {:fields => [[:int8, :a,
|
105
|
+
{:initial_value => lambda { parent.index }}],
|
106
|
+
[:int8, :b]]}]
|
107
|
+
@data = BinData::Array.new(:type => type, :initial_length => 5)
|
108
|
+
end
|
109
|
+
|
110
|
+
specify "should access elements, not values" do
|
111
|
+
@data[3].a.should == 3
|
112
|
+
end
|
113
|
+
|
114
|
+
specify "should not be able to modify elements" do
|
115
|
+
lambda { @data[1] = 3 }.should raise_error(NoMethodError)
|
116
|
+
end
|
117
|
+
|
118
|
+
specify "should interate over each element" do
|
119
|
+
@data.collect { |s| s.a }.should == [0, 1, 2, 3, 4]
|
120
|
+
end
|
121
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require 'bindata/base'
|
5
|
+
|
6
|
+
context "A data object with mandatory option" do
|
7
|
+
context_setup do
|
8
|
+
eval <<-END
|
9
|
+
class Mandatory < BinData::Base
|
10
|
+
mandatory_parameter :p1
|
11
|
+
end
|
12
|
+
END
|
13
|
+
end
|
14
|
+
specify "should ensure that those options are present" do
|
15
|
+
lambda { Mandatory.new(:p1 => "a") }.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should fail when those options are not present" do
|
19
|
+
lambda { Mandatory.new(:p2 => "a") }.should raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "A data object with mutually exclusive options" do
|
24
|
+
context_setup do
|
25
|
+
eval <<-END
|
26
|
+
class MutexParam < BinData::Base
|
27
|
+
optional_parameters :p1, :p2
|
28
|
+
def initialize(params = {}, env = nil)
|
29
|
+
super(params, env)
|
30
|
+
ensure_mutual_exclusion(:p1, :p2)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
END
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should not fail when neither of those options is present" do
|
37
|
+
lambda { MutexParam.new }.should_not raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "should not fail when only one of those options is present" do
|
41
|
+
lambda { MutexParam.new(:p1 => "a") }.should_not raise_error
|
42
|
+
lambda { MutexParam.new(:p2 => "a") }.should_not raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "should fail when both those options are present" do
|
46
|
+
lambda { MutexParam.new(:p1 => "a", :p2 => "b") }.should raise_error(ArgumentError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "A data object with parameters" do
|
51
|
+
context_setup do
|
52
|
+
eval <<-END
|
53
|
+
class WithParam < BinData::Base
|
54
|
+
mandatory_parameter :p1
|
55
|
+
optional_parameters :p2, :p3
|
56
|
+
public :has_param?, :eval_param, :param
|
57
|
+
end
|
58
|
+
END
|
59
|
+
end
|
60
|
+
|
61
|
+
specify "should not allow nil parameters" do
|
62
|
+
lambda { WithParam.new(:p1 => 1, :p2 => nil) }.should raise_error(ArgumentError)
|
63
|
+
end
|
64
|
+
|
65
|
+
specify "should identify extra parameters" do
|
66
|
+
env = mock("env")
|
67
|
+
env.should_receive(:params=).with(:p4 => 4, :p5 => 5)
|
68
|
+
env.should_receive(:data_object=)
|
69
|
+
obj = WithParam.new({:p1 => 1, :p3 => 3, :p4 => 4, :p5 => 5}, env)
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should only recall mandatory and optional parameters" do
|
73
|
+
obj = WithParam.new(:p1 => 1, :p3 => 3, :p4 => 4, :p5 => 5)
|
74
|
+
obj.should have_param(:p1)
|
75
|
+
obj.should_not have_param(:p2)
|
76
|
+
obj.should have_param(:p3)
|
77
|
+
obj.should_not have_param(:p4)
|
78
|
+
obj.should_not have_param(:p5)
|
79
|
+
end
|
80
|
+
|
81
|
+
specify "should evaluate mandatory and optional parameters" do
|
82
|
+
obj = WithParam.new(:p1 => 1, :p3 => lambda {1 + 2}, :p4 => 4, :p5 => 5)
|
83
|
+
obj.eval_param(:p1).should == 1
|
84
|
+
obj.eval_param(:p2).should_be_nil
|
85
|
+
obj.eval_param(:p3).should == 3
|
86
|
+
obj.eval_param(:p4).should_be_nil
|
87
|
+
obj.eval_param(:p5).should_be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
specify "should be able to access without evaluating" do
|
91
|
+
obj = WithParam.new(:p1 => :asym, :p3 => lambda {1 + 2})
|
92
|
+
obj.param(:p1).should == :asym
|
93
|
+
obj.param(:p2).should_be_nil
|
94
|
+
obj.param(:p3).should respond_to(:arity)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "A data object with :check_offset" do
|
99
|
+
context_setup do
|
100
|
+
eval <<-END
|
101
|
+
class TenByteOffset < BinData::Base
|
102
|
+
def do_read(io)
|
103
|
+
# advance the io position before checking offset
|
104
|
+
io.seek(10, IO::SEEK_CUR)
|
105
|
+
super(io)
|
106
|
+
end
|
107
|
+
def _do_read(io) end
|
108
|
+
def done_read; end
|
109
|
+
def clear; end
|
110
|
+
end
|
111
|
+
END
|
112
|
+
end
|
113
|
+
|
114
|
+
specify "should fail if offset is incorrect" do
|
115
|
+
io = StringIO.new("12345678901234567890")
|
116
|
+
io.seek(2)
|
117
|
+
obj = TenByteOffset.new(:check_offset => 8)
|
118
|
+
lambda { obj.read(io) }.should raise_error(BinData::ValidityError)
|
119
|
+
end
|
120
|
+
|
121
|
+
specify "should succeed if offset is correct" do
|
122
|
+
io = StringIO.new("12345678901234567890")
|
123
|
+
io.seek(3)
|
124
|
+
obj = TenByteOffset.new(:check_offset => 10)
|
125
|
+
lambda { obj.read(io) }.should_not raise_error
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "should fail if :check_offset fails" do
|
129
|
+
io = StringIO.new("12345678901234567890")
|
130
|
+
io.seek(4)
|
131
|
+
obj = TenByteOffset.new(:check_offset => lambda { offset == 11 } )
|
132
|
+
lambda { obj.read(io) }.should raise_error(BinData::ValidityError)
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should succeed if :check_offset succeeds" do
|
136
|
+
io = StringIO.new("12345678901234567890")
|
137
|
+
io.seek(5)
|
138
|
+
obj = TenByteOffset.new(:check_offset => lambda { offset == 10 } )
|
139
|
+
lambda { obj.read(io) }.should_not raise_error
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "A data object with :readwrite => false" do
|
144
|
+
context_setup do
|
145
|
+
eval <<-END
|
146
|
+
class NoIO < BinData::Base
|
147
|
+
def _do_read(io)
|
148
|
+
@_do_read = true
|
149
|
+
end
|
150
|
+
def _write(io)
|
151
|
+
@_do_write = true
|
152
|
+
end
|
153
|
+
def _num_bytes
|
154
|
+
5
|
155
|
+
end
|
156
|
+
def done_read; end
|
157
|
+
def clear; end
|
158
|
+
attr_reader :_do_read, :_do_write
|
159
|
+
end
|
160
|
+
END
|
161
|
+
@obj = NoIO.new :readwrite => false
|
162
|
+
end
|
163
|
+
|
164
|
+
specify "should not read" do
|
165
|
+
io = StringIO.new("12345678901234567890")
|
166
|
+
@obj.read(io)
|
167
|
+
@obj._do_read.should_not == true
|
168
|
+
end
|
169
|
+
|
170
|
+
specify "should not write" do
|
171
|
+
io = StringIO.new
|
172
|
+
@obj.write(io)
|
173
|
+
@obj._do_write.should_not == true
|
174
|
+
end
|
175
|
+
|
176
|
+
specify "should have zero num_bytes" do
|
177
|
+
@obj.num_bytes.should == 0
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "A data object defining a value method" do
|
182
|
+
context_setup do
|
183
|
+
eval <<-END
|
184
|
+
class SingleValueObject < BinData::Base
|
185
|
+
def value; end
|
186
|
+
end
|
187
|
+
END
|
188
|
+
end
|
189
|
+
|
190
|
+
specify "should be a single value object" do
|
191
|
+
obj = SingleValueObject.new
|
192
|
+
obj.should be_a_single_value
|
193
|
+
end
|
194
|
+
end
|
data/spec/choice_spec.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require 'bindata/choice'
|
5
|
+
require 'bindata/int'
|
6
|
+
require 'bindata/lazy'
|
7
|
+
require 'bindata/struct'
|
8
|
+
|
9
|
+
context "Instantiating a Choice" do
|
10
|
+
specify "should ensure mandatory parameters are supplied" do
|
11
|
+
args = {}
|
12
|
+
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
13
|
+
args = {:selection => 1}
|
14
|
+
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
15
|
+
args = {:choices => []}
|
16
|
+
lambda { BinData::Choice.new(args) }.should raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "should fail if a given type is unknown" do
|
20
|
+
args = {:choices => [:does_not_exist], :selection => 0}
|
21
|
+
lambda { BinData::Choice.new(args) }.should raise_error(TypeError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "A Choice with several choices" do
|
26
|
+
setup do
|
27
|
+
# allow specifications to select the choice
|
28
|
+
@env = BinData::LazyEvalEnv.new
|
29
|
+
@env.class.class_eval { attr_accessor :choose }
|
30
|
+
|
31
|
+
@data = BinData::Choice.new({:choices => [[:int8, {:initial_value => 3}],
|
32
|
+
[:int16le, {:initial_value => 5}],
|
33
|
+
:int8,
|
34
|
+
[:struct,
|
35
|
+
{:fields =>[[:int8, :a]]}],
|
36
|
+
[:int8, {:initial_value => 7}]],
|
37
|
+
:selection => :choose},
|
38
|
+
@env)
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "should be able to select the choice" do
|
42
|
+
@env.choose = 0
|
43
|
+
@data.value.should == 3
|
44
|
+
@env.choose = 1
|
45
|
+
@data.value.should == 5
|
46
|
+
@env.choose = 2
|
47
|
+
@data.value.should == 0
|
48
|
+
@env.choose = 3
|
49
|
+
@data.a.should == 0
|
50
|
+
@env.choose = 4
|
51
|
+
@data.value.should == 7
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "should not be able to select an invalid choice" do
|
55
|
+
@env.choose = -1
|
56
|
+
lambda { @data.value }.should raise_error(IndexError)
|
57
|
+
@env.choose = 5
|
58
|
+
lambda { @data.value }.should raise_error(IndexError)
|
59
|
+
end
|
60
|
+
|
61
|
+
specify "should be able to interact directly with the choice" do
|
62
|
+
@env.choose = 0
|
63
|
+
@data.value = 17
|
64
|
+
@data.value.should == 17
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "should handle missing methods correctly" do
|
68
|
+
@env.choose = 0
|
69
|
+
|
70
|
+
@data.should respond_to(:value)
|
71
|
+
@data.should_not respond_to(:does_not_exist)
|
72
|
+
lambda { @data.does_not_exist }.should raise_error(NoMethodError)
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "should delegate methods to the selected single choice" do
|
76
|
+
@env.choose = 1
|
77
|
+
@data.value = 17
|
78
|
+
|
79
|
+
@data.find_obj_for_name("does_not_exist").should be_nil
|
80
|
+
@data.num_bytes.should == 2
|
81
|
+
@data.field_names.should be_empty
|
82
|
+
@data.value.should == 17
|
83
|
+
|
84
|
+
io = StringIO.new
|
85
|
+
@data.write(io)
|
86
|
+
|
87
|
+
@data.clear
|
88
|
+
@data.clear?.should be_true
|
89
|
+
@data.value.should == 5
|
90
|
+
|
91
|
+
io.rewind
|
92
|
+
@data.read(io)
|
93
|
+
@data.value.should == 17
|
94
|
+
|
95
|
+
@data.snapshot.should == 17
|
96
|
+
end
|
97
|
+
|
98
|
+
specify "should delegate methods to the selected complex choice" do
|
99
|
+
@env.choose = 3
|
100
|
+
@data.find_obj_for_name("a").should_not be_nil
|
101
|
+
@data.field_names.should == ["a"]
|
102
|
+
@data.num_bytes.should == 1
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
data/spec/int_spec.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require 'bindata/int'
|
5
|
+
|
6
|
+
context "All signed integers" do
|
7
|
+
specify "should have a sensible value of zero" do
|
8
|
+
[BinData::Int8,
|
9
|
+
BinData::Int16le,
|
10
|
+
BinData::Int16be,
|
11
|
+
BinData::Int32le,
|
12
|
+
BinData::Int32be].each do |klass|
|
13
|
+
klass.new.value.should == 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
specify "should pass these tests" do
|
18
|
+
[
|
19
|
+
[1, true, BinData::Int8],
|
20
|
+
[2, false, BinData::Int16le],
|
21
|
+
[2, true, BinData::Int16be],
|
22
|
+
[4, false, BinData::Int32le],
|
23
|
+
[4, true, BinData::Int32be],
|
24
|
+
].each do |nbytes, big_endian, klass|
|
25
|
+
gen_int_test_data(nbytes, big_endian).each do |val, clamped_val, str|
|
26
|
+
test_read_write(klass, val, clamped_val, str)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "All unsigned integers" do
|
33
|
+
specify "should have a sensible value of zero" do
|
34
|
+
[BinData::Uint8,
|
35
|
+
BinData::Uint16le,
|
36
|
+
BinData::Uint16be,
|
37
|
+
BinData::Uint32le,
|
38
|
+
BinData::Uint32be].each do |klass|
|
39
|
+
klass.new.value.should == 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "should pass these tests" do
|
44
|
+
[
|
45
|
+
[1, true, BinData::Uint8],
|
46
|
+
[2, false, BinData::Uint16le],
|
47
|
+
[2, true, BinData::Uint16be],
|
48
|
+
[4, false, BinData::Uint32le],
|
49
|
+
[4, true, BinData::Uint32be],
|
50
|
+
].each do |nbytes, big_endian, klass|
|
51
|
+
gen_uint_test_data(nbytes, big_endian).each do |val, clamped_val, str|
|
52
|
+
test_read_write(klass, val, clamped_val, str)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# run read / write tests for the given values
|
59
|
+
def test_read_write(klass, val, clamped_val, str)
|
60
|
+
# set the data and ensure clamping occurs
|
61
|
+
data = klass.new
|
62
|
+
data.value = val
|
63
|
+
data.value.should == clamped_val
|
64
|
+
|
65
|
+
# write the data
|
66
|
+
io = StringIO.new
|
67
|
+
data.write(io)
|
68
|
+
|
69
|
+
# check that we write the expected byte pattern
|
70
|
+
io.rewind
|
71
|
+
io.read.should == str
|
72
|
+
|
73
|
+
# check that we read in the same data that was written
|
74
|
+
io.rewind
|
75
|
+
data = klass.new
|
76
|
+
data.read(io)
|
77
|
+
data.value.should == clamped_val
|
78
|
+
end
|
79
|
+
|
80
|
+
# return test data for testing unsigned ints
|
81
|
+
def gen_uint_test_data(nbytes, big_endian)
|
82
|
+
raise "nbytes too big" if nbytes > 8
|
83
|
+
tests = []
|
84
|
+
|
85
|
+
# test the minimum value
|
86
|
+
v = 0
|
87
|
+
s = "\x00" * nbytes
|
88
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
89
|
+
|
90
|
+
# values below minimum should be clamped to minimum
|
91
|
+
tests.push [v-1, v, big_endian ? s : s.reverse]
|
92
|
+
|
93
|
+
# test a value within range
|
94
|
+
v = 0x123456789abcdef0 >> ((8-nbytes) * 8)
|
95
|
+
s = "\x12\x34\x56\x78\x9a\xbc\xde\xf0".slice(0, nbytes)
|
96
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
97
|
+
|
98
|
+
# test the maximum value
|
99
|
+
v = (1 << (nbytes * 8)) - 1
|
100
|
+
s = "\xff" * nbytes
|
101
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
102
|
+
|
103
|
+
# values above maximum should be clamped to maximum
|
104
|
+
tests.push [v+1, v, big_endian ? s : s.reverse]
|
105
|
+
|
106
|
+
tests
|
107
|
+
end
|
108
|
+
|
109
|
+
# return test data for testing signed ints
|
110
|
+
def gen_int_test_data(nbytes, big_endian)
|
111
|
+
raise "nbytes too big" if nbytes > 8
|
112
|
+
tests = []
|
113
|
+
|
114
|
+
# test the minimum value
|
115
|
+
v = -((1 << (nbytes * 8 - 1)) - 1) -1
|
116
|
+
s = "\x80\x00\x00\x00\x00\x00\x00\x00".slice(0, nbytes)
|
117
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
118
|
+
|
119
|
+
# values below minimum should be clamped to minimum
|
120
|
+
tests.push [v-1, v, big_endian ? s : s.reverse]
|
121
|
+
|
122
|
+
# test a -ve value within range
|
123
|
+
v = -1
|
124
|
+
s = "\xff" * nbytes
|
125
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
126
|
+
|
127
|
+
# test a +ve value within range
|
128
|
+
v = 0x123456789abcdef0 >> ((8-nbytes) * 8)
|
129
|
+
s = "\x12\x34\x56\x78\x9a\xbc\xde\xf0".slice(0, nbytes)
|
130
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
131
|
+
|
132
|
+
# test the maximum value
|
133
|
+
v = (1 << (nbytes * 8 - 1)) - 1
|
134
|
+
s = "\x7f" + "\xff" * (nbytes - 1)
|
135
|
+
tests.push [v, v, big_endian ? s : s.reverse]
|
136
|
+
|
137
|
+
# values above maximum should be clamped to maximum
|
138
|
+
tests.push [v+1, v, big_endian ? s : s.reverse]
|
139
|
+
|
140
|
+
tests
|
141
|
+
end
|