bindata 1.8.0 → 1.8.1
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.rdoc +4 -0
- data/lib/bindata/bits.rb +37 -13
- data/lib/bindata/registry.rb +1 -1
- data/lib/bindata/version.rb +1 -1
- data/test/bits_test.rb +64 -10
- data/test/registry_test.rb +8 -0
- metadata +4 -4
data/ChangeLog.rdoc
CHANGED
data/lib/bindata/bits.rb
CHANGED
@@ -6,13 +6,13 @@ module BinData
|
|
6
6
|
|
7
7
|
module BitField #:nodoc: all
|
8
8
|
class << self
|
9
|
-
def define_class(nbits, endian)
|
10
|
-
name = "Bit
|
9
|
+
def define_class(nbits, endian, signed = :unsigned)
|
10
|
+
name = ((signed == :signed ) ? "Sbit" : "Bit") + nbits.to_s
|
11
11
|
name << "le" if endian == :little
|
12
12
|
unless BinData.const_defined?(name)
|
13
13
|
BinData.module_eval <<-END
|
14
14
|
class #{name} < BinData::BasePrimitive
|
15
|
-
BitField.define_methods(self, #{nbits}, :#{endian})
|
15
|
+
BitField.define_methods(self, #{nbits}, :#{endian}, :#{signed})
|
16
16
|
end
|
17
17
|
END
|
18
18
|
end
|
@@ -20,15 +20,17 @@ module BinData
|
|
20
20
|
BinData.const_get(name)
|
21
21
|
end
|
22
22
|
|
23
|
-
def define_methods(bit_class, nbits, endian)
|
23
|
+
def define_methods(bit_class, nbits, endian, signed)
|
24
24
|
bit_class.module_eval <<-END
|
25
25
|
def assign(val)
|
26
|
-
#{create_clamp_code(nbits)}
|
26
|
+
#{create_clamp_code(nbits, signed)}
|
27
27
|
super(val)
|
28
28
|
end
|
29
29
|
|
30
30
|
def do_write(io)
|
31
|
-
|
31
|
+
val = _value
|
32
|
+
#{create_int2uint_code(nbits) if signed == :signed}
|
33
|
+
io.writebits(val, #{nbits}, :#{endian})
|
32
34
|
end
|
33
35
|
|
34
36
|
def do_num_bytes
|
@@ -39,7 +41,9 @@ module BinData
|
|
39
41
|
private
|
40
42
|
|
41
43
|
def read_and_return_value(io)
|
42
|
-
io.readbits(#{nbits}, :#{endian})
|
44
|
+
val = io.readbits(#{nbits}, :#{endian})
|
45
|
+
#{create_uint2int_code(nbits) if signed == :signed}
|
46
|
+
val
|
43
47
|
end
|
44
48
|
|
45
49
|
def sensible_default
|
@@ -48,9 +52,19 @@ module BinData
|
|
48
52
|
END
|
49
53
|
end
|
50
54
|
|
51
|
-
def create_clamp_code(nbits)
|
52
|
-
|
53
|
-
|
55
|
+
def create_clamp_code(nbits, signed)
|
56
|
+
if nbits == 1 and signed == :signed
|
57
|
+
raise "signed bitfield must have more than one bit"
|
58
|
+
end
|
59
|
+
|
60
|
+
if signed == :signed
|
61
|
+
max = (1 << (nbits - 1)) - 1
|
62
|
+
min = -(max + 1)
|
63
|
+
else
|
64
|
+
min = 0
|
65
|
+
max = (1 << nbits) - 1
|
66
|
+
end
|
67
|
+
|
54
68
|
clamp = "(val < #{min}) ? #{min} : (val > #{max}) ? #{max} : val"
|
55
69
|
|
56
70
|
if nbits == 1
|
@@ -60,6 +74,14 @@ module BinData
|
|
60
74
|
|
61
75
|
"val = #{clamp}"
|
62
76
|
end
|
77
|
+
|
78
|
+
def create_int2uint_code(nbits)
|
79
|
+
"val = val & #{(1 << nbits) - 1}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_uint2int_code(nbits)
|
83
|
+
"val = val - #{1 << nbits} if (val >= #{1 << (nbits - 1)})"
|
84
|
+
end
|
63
85
|
end
|
64
86
|
end
|
65
87
|
|
@@ -68,13 +90,15 @@ module BinData
|
|
68
90
|
def const_missing(name)
|
69
91
|
mappings = {
|
70
92
|
/^Bit(\d+)$/ => :big,
|
71
|
-
/^Bit(\d+)le$/ => :little
|
93
|
+
/^Bit(\d+)le$/ => :little,
|
94
|
+
/^Sbit(\d+)$/ => [:big, :signed],
|
95
|
+
/^Sbit(\d+)le$/ => [:little, :signed]
|
72
96
|
}
|
73
97
|
|
74
|
-
mappings.each_pair do |regex,
|
98
|
+
mappings.each_pair do |regex, args|
|
75
99
|
if regex =~ name.to_s
|
76
100
|
nbits = $1.to_i
|
77
|
-
return BitField.define_class(nbits,
|
101
|
+
return BitField.define_class(nbits, *args)
|
78
102
|
end
|
79
103
|
end
|
80
104
|
|
data/lib/bindata/registry.rb
CHANGED
@@ -73,7 +73,7 @@ module BinData
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def register_dynamic_class(name)
|
76
|
-
if /^u?int\d+(le|be)$/ =~ name or /^bit\d+(le)?$/ =~ name
|
76
|
+
if /^u?int\d+(le|be)$/ =~ name or /^s?bit\d+(le)?$/ =~ name
|
77
77
|
class_name = name.gsub(/(?:^|_)(.)/) { $1.upcase }
|
78
78
|
begin
|
79
79
|
BinData::const_get(class_name)
|
data/lib/bindata/version.rb
CHANGED
data/test/bits_test.rb
CHANGED
@@ -69,11 +69,19 @@ module AllBitfields
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def min_value
|
72
|
-
|
72
|
+
if @signed
|
73
|
+
-max_value - 1
|
74
|
+
else
|
75
|
+
0
|
76
|
+
end
|
73
77
|
end
|
74
78
|
|
75
79
|
def max_value
|
76
|
-
|
80
|
+
if @signed
|
81
|
+
(1 << (@nbits - 1)) - 1
|
82
|
+
else
|
83
|
+
(1 << @nbits) - 1
|
84
|
+
end
|
77
85
|
end
|
78
86
|
|
79
87
|
def some_values_within_range
|
@@ -89,21 +97,31 @@ module AllBitfields
|
|
89
97
|
end
|
90
98
|
end
|
91
99
|
|
92
|
-
def generate_bit_classes_to_test(endian)
|
100
|
+
def generate_bit_classes_to_test(endian, signed)
|
93
101
|
bits = {}
|
94
|
-
|
95
|
-
|
102
|
+
if signed
|
103
|
+
base = "Sbit"
|
104
|
+
start = 2
|
105
|
+
else
|
106
|
+
base = "Bit"
|
107
|
+
start = 1
|
108
|
+
end
|
109
|
+
|
110
|
+
(start .. 50).each do |nbits|
|
111
|
+
name = "#{base}#{nbits}"
|
112
|
+
name << "le" if endian == :little
|
96
113
|
bit_class = BinData.const_get(name)
|
97
114
|
bits[bit_class] = nbits
|
98
115
|
end
|
99
116
|
bits
|
100
117
|
end
|
101
118
|
|
102
|
-
describe "
|
119
|
+
describe "Unsigned big endian bitfields" do
|
103
120
|
include AllBitfields
|
104
121
|
|
105
122
|
before do
|
106
|
-
@
|
123
|
+
@signed = false
|
124
|
+
@bits = generate_bit_classes_to_test(:big, @signed)
|
107
125
|
end
|
108
126
|
|
109
127
|
it "read big endian values" do
|
@@ -116,11 +134,48 @@ describe "Big endian bitfields" do
|
|
116
134
|
end
|
117
135
|
end
|
118
136
|
|
119
|
-
describe "
|
137
|
+
describe "Signed big endian bitfields" do
|
138
|
+
include AllBitfields
|
139
|
+
|
140
|
+
before do
|
141
|
+
@signed = true
|
142
|
+
@bits = generate_bit_classes_to_test(:big, @signed)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "read big endian values" do
|
146
|
+
@bits.each_pair do |bit_class, nbits|
|
147
|
+
nbytes = (nbits + 7) / 8
|
148
|
+
str = [0b0100_0000].pack("C") + "\000" * (nbytes - 1)
|
149
|
+
|
150
|
+
bit_class.read(str).must_equal 1 << (nbits - 2)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "Unsigned little endian bitfields" do
|
120
156
|
include AllBitfields
|
121
157
|
|
122
158
|
before do
|
123
|
-
@
|
159
|
+
@signed = false
|
160
|
+
@bits = generate_bit_classes_to_test(:little, @signed)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "read little endian values" do
|
164
|
+
@bits.each_pair do |bit_class, nbits|
|
165
|
+
nbytes = (nbits + 7) / 8
|
166
|
+
str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
|
167
|
+
|
168
|
+
bit_class.read(str).must_equal 1
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Signed little endian bitfields" do
|
174
|
+
include AllBitfields
|
175
|
+
|
176
|
+
before do
|
177
|
+
@signed = true
|
178
|
+
@bits = generate_bit_classes_to_test(:little, @signed)
|
124
179
|
end
|
125
180
|
|
126
181
|
it "read little endian values" do
|
@@ -160,4 +215,3 @@ describe "Bits of size 1" do
|
|
160
215
|
end
|
161
216
|
end
|
162
217
|
end
|
163
|
-
|
data/test/registry_test.rb
CHANGED
@@ -92,6 +92,7 @@ describe BinData::Registry, "with numerics" do
|
|
92
92
|
|
93
93
|
it "lookup bits" do
|
94
94
|
r.lookup("bit5").to_s.must_equal "BinData::Bit5"
|
95
|
+
r.lookup("sbit5").to_s.must_equal "BinData::Sbit5"
|
95
96
|
r.lookup("bit6le").to_s.must_equal "BinData::Bit6le"
|
96
97
|
end
|
97
98
|
|
@@ -101,6 +102,13 @@ describe BinData::Registry, "with numerics" do
|
|
101
102
|
r.lookup("bit2", :little).to_s.must_equal "BinData::Bit2"
|
102
103
|
r.lookup("bit3le", :little).to_s.must_equal "BinData::Bit3le"
|
103
104
|
end
|
105
|
+
|
106
|
+
it "lookup signed bits by ignoring endian" do
|
107
|
+
r.lookup("sbit2", :big).to_s.must_equal "BinData::Sbit2"
|
108
|
+
r.lookup("sbit3le", :big).to_s.must_equal "BinData::Sbit3le"
|
109
|
+
r.lookup("sbit2", :little).to_s.must_equal "BinData::Sbit2"
|
110
|
+
r.lookup("sbit3le", :little).to_s.must_equal "BinData::Sbit3le"
|
111
|
+
end
|
104
112
|
end
|
105
113
|
|
106
114
|
describe BinData::Registry, "with endian specific types" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bindata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 53
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 1.8.
|
9
|
+
- 1
|
10
|
+
version: 1.8.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dion Mendel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2014-01-
|
18
|
+
date: 2014-01-15 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|