bindata 0.11.0 → 0.11.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 +6 -0
- data/TODO +17 -0
- data/TUTORIAL +949 -0
- data/lib/bindata.rb +1 -1
- data/lib/bindata/array.rb +4 -4
- data/lib/bindata/choice.rb +1 -1
- data/lib/bindata/deprecated.rb +2 -2
- data/lib/bindata/float.rb +5 -5
- data/lib/bindata/int.rb +33 -28
- data/lib/bindata/registry.rb +2 -2
- data/lib/bindata/sanitize.rb +1 -0
- data/lib/bindata/struct.rb +4 -4
- data/spec/array_spec.rb +1 -1
- data/spec/base_primitive_spec.rb +3 -7
- data/spec/base_spec.rb +29 -59
- data/spec/deprecated_spec.rb +4 -8
- data/spec/int_spec.rb +25 -60
- data/spec/primitive_spec.rb +37 -65
- data/spec/record_spec.rb +63 -105
- data/spec/registry_spec.rb +6 -6
- data/spec/system_spec.rb +32 -56
- data/spec/wrapper_spec.rb +28 -29
- metadata +3 -2
data/lib/bindata.rb
CHANGED
data/lib/bindata/array.rb
CHANGED
@@ -95,7 +95,7 @@ module BinData
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def find_index(obj)
|
98
|
-
elements.
|
98
|
+
elements.index(obj)
|
99
99
|
end
|
100
100
|
alias_method :index, :find_index
|
101
101
|
|
@@ -103,7 +103,7 @@ module BinData
|
|
103
103
|
#
|
104
104
|
# Uses equal? for the comparator.
|
105
105
|
def find_index_of(obj)
|
106
|
-
elements.
|
106
|
+
elements.index { |el| el.equal?(obj) }
|
107
107
|
end
|
108
108
|
|
109
109
|
def push(*args)
|
@@ -222,7 +222,7 @@ module BinData
|
|
222
222
|
index = find_index_of(child)
|
223
223
|
sum = sum_num_bytes_below_index(index)
|
224
224
|
|
225
|
-
child_offset =
|
225
|
+
child_offset = child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor
|
226
226
|
|
227
227
|
offset + child_offset
|
228
228
|
end
|
@@ -337,7 +337,7 @@ module BinData
|
|
337
337
|
sum = 0
|
338
338
|
(0...index).each do |i|
|
339
339
|
nbytes = elements[i].do_num_bytes
|
340
|
-
sum = ((
|
340
|
+
sum = (nbytes.is_a?(Integer) ? sum.ceil : sum) + nbytes
|
341
341
|
end
|
342
342
|
|
343
343
|
sum
|
data/lib/bindata/choice.rb
CHANGED
@@ -92,7 +92,7 @@ module BinData
|
|
92
92
|
if choices.has_key?(nil)
|
93
93
|
raise ArgumentError, ":choices hash may not have nil key"
|
94
94
|
end
|
95
|
-
if choices.keys.detect { |key| Symbol
|
95
|
+
if choices.keys.detect { |key| key.is_a?(Symbol) }
|
96
96
|
raise ArgumentError, ":choices hash may not have symbols for keys"
|
97
97
|
end
|
98
98
|
end
|
data/lib/bindata/deprecated.rb
CHANGED
@@ -139,8 +139,8 @@ module BinData
|
|
139
139
|
|
140
140
|
alias_method :orig_offset_of, :offset_of
|
141
141
|
def offset_of(child)
|
142
|
-
if child.
|
143
|
-
fail "error: 'offset_of(
|
142
|
+
if child.is_a?(::String) or child.is_a?(Symbol)
|
143
|
+
fail "error: 'offset_of(#{child.inspect})' is deprecated. Use '#{child.to_s}.offset' instead"
|
144
144
|
end
|
145
145
|
orig_offset_of(child)
|
146
146
|
end
|
data/lib/bindata/float.rb
CHANGED
@@ -7,10 +7,10 @@ module BinData
|
|
7
7
|
module FloatingPoint #:nodoc: all
|
8
8
|
def self.create_float_methods(float_class, precision, endian)
|
9
9
|
read = create_read_code(precision, endian)
|
10
|
-
|
10
|
+
to_binary_s = create_to_binary_s_code(precision, endian)
|
11
11
|
nbytes = (precision == :single) ? 4 : 8
|
12
12
|
|
13
|
-
define_methods(float_class, nbytes, read,
|
13
|
+
define_methods(float_class, nbytes, read, to_binary_s)
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.create_read_code(precision, endian)
|
@@ -25,7 +25,7 @@ module BinData
|
|
25
25
|
"io.readbytes(#{nbytes}).unpack('#{unpack}').at(0)"
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.
|
28
|
+
def self.create_to_binary_s_code(precision, endian)
|
29
29
|
if precision == :single
|
30
30
|
pack = (endian == :little) ? 'e' : 'g'
|
31
31
|
else # double_precision
|
@@ -35,7 +35,7 @@ module BinData
|
|
35
35
|
"[val].pack('#{pack}')"
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.define_methods(float_class, nbytes, read,
|
38
|
+
def self.define_methods(float_class, nbytes, read, to_binary_s)
|
39
39
|
float_class.module_eval <<-END
|
40
40
|
def _do_num_bytes(ignored)
|
41
41
|
#{nbytes}
|
@@ -49,7 +49,7 @@ module BinData
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def value_to_binary_string(val)
|
52
|
-
#{
|
52
|
+
#{to_binary_s}
|
53
53
|
end
|
54
54
|
|
55
55
|
def read_and_return_value(io)
|
data/lib/bindata/int.rb
CHANGED
@@ -4,49 +4,58 @@ module BinData
|
|
4
4
|
# Defines a number of classes that contain an integer. The integer
|
5
5
|
# is defined by endian, signedness and number of bytes.
|
6
6
|
|
7
|
-
module
|
7
|
+
module Int #:nodoc: all
|
8
8
|
class << self
|
9
9
|
def define_class(nbits, endian, signed)
|
10
|
-
|
11
|
-
if
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
name = "Uint#{nbits}#{endian_str}"
|
16
|
-
creation_method = "create_uint_methods"
|
17
|
-
end
|
10
|
+
name = class_name(nbits, endian, signed)
|
11
|
+
return if BinData.const_defined?(name)
|
12
|
+
|
13
|
+
int_type = (signed == :signed) ? 'int' : 'uint'
|
14
|
+
creation_method = "create_#{int_type}_methods"
|
18
15
|
|
19
16
|
BinData.module_eval <<-END
|
20
17
|
class #{name} < BinData::BasePrimitive
|
21
18
|
register(self.name, self)
|
22
|
-
|
19
|
+
Int.#{creation_method}(self, #{nbits}, :#{endian.to_s})
|
23
20
|
end
|
24
21
|
END
|
25
22
|
end
|
26
23
|
|
24
|
+
def class_name(nbits, endian, signed)
|
25
|
+
endian_str = (endian == :big) ? "be" : "le"
|
26
|
+
base = (signed == :signed) ? "Int" : "Uint"
|
27
|
+
|
28
|
+
"#{base}#{nbits}#{endian_str}"
|
29
|
+
end
|
30
|
+
|
27
31
|
def create_uint_methods(int_class, nbits, endian)
|
32
|
+
raise "nbits must be divisible by 8" unless (nbits % 8).zero?
|
33
|
+
|
28
34
|
min = 0
|
29
35
|
max = (1 << nbits) - 1
|
30
36
|
|
31
37
|
clamp = create_clamp_code(min, max)
|
32
38
|
read = create_read_code(nbits, endian)
|
33
|
-
|
39
|
+
to_binary_s = create_to_binary_s_code(nbits, endian)
|
34
40
|
|
35
|
-
define_methods(int_class, nbits / 8, clamp, read,
|
41
|
+
define_methods(int_class, nbits / 8, clamp, read, to_binary_s)
|
36
42
|
end
|
37
43
|
|
38
44
|
def create_int_methods(int_class, nbits, endian)
|
45
|
+
raise "nbits must be divisible by 8" unless (nbits % 8).zero?
|
46
|
+
|
39
47
|
max = (1 << (nbits - 1)) - 1
|
40
48
|
min = -(max + 1)
|
41
49
|
|
42
50
|
clamp = create_clamp_code(min, max)
|
43
51
|
read = create_read_code(nbits, endian)
|
44
|
-
|
52
|
+
to_binary_s = create_to_binary_s_code(nbits, endian)
|
45
53
|
|
46
54
|
int2uint = create_int2uint_code(nbits)
|
47
55
|
uint2int = create_uint2int_code(nbits)
|
48
56
|
|
49
|
-
define_methods(int_class, nbits / 8, clamp, read,
|
57
|
+
define_methods(int_class, nbits / 8, clamp, read, to_binary_s,
|
58
|
+
int2uint, uint2int)
|
50
59
|
end
|
51
60
|
|
52
61
|
def create_clamp_code(min, max)
|
@@ -65,8 +74,6 @@ module BinData
|
|
65
74
|
end
|
66
75
|
|
67
76
|
def create_read_code(nbits, endian)
|
68
|
-
raise "nbits must be divisible by 8" unless (nbits % 8).zero?
|
69
|
-
|
70
77
|
# determine "word" size and unpack directive
|
71
78
|
if (nbits % 32).zero?
|
72
79
|
bytes_per_word = 4
|
@@ -97,9 +104,7 @@ module BinData
|
|
97
104
|
"(#{unpack_str}; #{assemble_str})"
|
98
105
|
end
|
99
106
|
|
100
|
-
def
|
101
|
-
raise "nbits must be divisible by 8" unless (nbits % 8).zero?
|
102
|
-
|
107
|
+
def create_to_binary_s_code(nbits, endian)
|
103
108
|
# special case 8bit integers for speed
|
104
109
|
return "val.chr" if nbits == 8
|
105
110
|
|
@@ -130,8 +135,8 @@ module BinData
|
|
130
135
|
"#{array_str}.pack('#{d * nwords}')"
|
131
136
|
end
|
132
137
|
|
133
|
-
def define_methods(int_class, nbytes, clamp, read,
|
134
|
-
|
138
|
+
def define_methods(int_class, nbytes, clamp, read, to_binary_s,
|
139
|
+
int2uint = nil, uint2int = nil)
|
135
140
|
int_class.module_eval <<-END
|
136
141
|
#---------------
|
137
142
|
private
|
@@ -152,7 +157,7 @@ module BinData
|
|
152
157
|
def value_to_binary_string(val)
|
153
158
|
#{clamp}
|
154
159
|
#{int2uint unless int2uint.nil?}
|
155
|
-
#{
|
160
|
+
#{to_binary_s}
|
156
161
|
end
|
157
162
|
|
158
163
|
def read_and_return_value(io)
|
@@ -168,20 +173,20 @@ module BinData
|
|
168
173
|
# Unsigned 1 byte integer.
|
169
174
|
class Uint8 < BinData::BasePrimitive
|
170
175
|
register(self.name, self)
|
171
|
-
|
176
|
+
Int.create_uint_methods(self, 8, :little)
|
172
177
|
end
|
173
178
|
|
174
179
|
# Signed 1 byte integer.
|
175
180
|
class Int8 < BinData::BasePrimitive
|
176
181
|
register(self.name, self)
|
177
|
-
|
182
|
+
Int.create_int_methods(self, 8, :little)
|
178
183
|
end
|
179
184
|
|
180
185
|
# Create commonly used integers
|
181
186
|
[8, 16, 32, 64, 128].each do |nbits|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
187
|
+
Int.define_class(nbits, :little, :unsigned)
|
188
|
+
Int.define_class(nbits, :little, :signed)
|
189
|
+
Int.define_class(nbits, :big, :unsigned)
|
190
|
+
Int.define_class(nbits, :big, :signed)
|
186
191
|
end
|
187
192
|
end
|
data/lib/bindata/registry.rb
CHANGED
@@ -57,8 +57,8 @@ module BinData
|
|
57
57
|
nbits = $2.to_i
|
58
58
|
endian = $3 == "le" ? :little : :big
|
59
59
|
if nbits > 0 and (nbits % 8) == 0
|
60
|
-
if BinData.const_defined?(:
|
61
|
-
BinData::
|
60
|
+
if BinData.const_defined?(:Int)
|
61
|
+
BinData::Int.define_class(nbits, endian, signed)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
elsif /^bit(\d+)(le)?$/ =~ key
|
data/lib/bindata/sanitize.rb
CHANGED
data/lib/bindata/struct.rb
CHANGED
@@ -188,7 +188,7 @@ module BinData
|
|
188
188
|
def offset_of(child)
|
189
189
|
instantiate_all_objs
|
190
190
|
sum = sum_num_bytes_below_index(find_index_of(child))
|
191
|
-
child_offset =
|
191
|
+
child_offset = child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor
|
192
192
|
|
193
193
|
offset + child_offset
|
194
194
|
end
|
@@ -208,12 +208,12 @@ module BinData
|
|
208
208
|
end
|
209
209
|
|
210
210
|
def find_index_of(obj)
|
211
|
-
@field_objs.
|
211
|
+
@field_objs.index { |el| el.equal?(obj) }
|
212
212
|
end
|
213
213
|
|
214
214
|
def find_obj_for_name(name)
|
215
215
|
field_name = name.to_s.chomp("=")
|
216
|
-
index = @field_names.
|
216
|
+
index = @field_names.index(field_name)
|
217
217
|
if index
|
218
218
|
instantiate_obj_at(index)
|
219
219
|
@field_objs[index]
|
@@ -297,7 +297,7 @@ module BinData
|
|
297
297
|
obj = @field_objs[i]
|
298
298
|
if include_obj(obj)
|
299
299
|
nbytes = obj.do_num_bytes
|
300
|
-
sum = ((
|
300
|
+
sum = (nbytes.is_a?(Integer) ? sum.ceil : sum) + nbytes
|
301
301
|
end
|
302
302
|
end
|
303
303
|
|
data/spec/array_spec.rb
CHANGED
data/spec/base_primitive_spec.rb
CHANGED
@@ -13,16 +13,12 @@ class ExampleSingle
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe BinData::BasePrimitive, "when subclassing" do
|
16
|
-
|
17
|
-
|
18
|
-
class SubClassOfSingle < BinData::BasePrimitive
|
19
|
-
expose_methods_for_testing
|
20
|
-
end
|
21
|
-
END
|
16
|
+
class SubClassOfBasePrimitive < BinData::BasePrimitive
|
17
|
+
expose_methods_for_testing
|
22
18
|
end
|
23
19
|
|
24
20
|
before(:each) do
|
25
|
-
@obj =
|
21
|
+
@obj = SubClassOfBasePrimitive.new
|
26
22
|
end
|
27
23
|
|
28
24
|
it "should raise errors on unimplemented methods" do
|
data/spec/base_spec.rb
CHANGED
@@ -30,12 +30,8 @@ class MockBaseStub < BaseStub
|
|
30
30
|
end
|
31
31
|
|
32
32
|
describe BinData::Base, "when subclassing" do
|
33
|
-
|
34
|
-
|
35
|
-
class SubClassOfBase < BinData::Base
|
36
|
-
expose_methods_for_testing
|
37
|
-
end
|
38
|
-
END
|
33
|
+
class SubClassOfBase < BinData::Base
|
34
|
+
expose_methods_for_testing
|
39
35
|
end
|
40
36
|
|
41
37
|
before(:each) do
|
@@ -63,11 +59,9 @@ describe BinData::Base, "with parameters" do
|
|
63
59
|
|
64
60
|
it "should raise error if parameter name is invalid" do
|
65
61
|
lambda {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
END
|
62
|
+
class InvalidParameterNameBase < BinData::Base
|
63
|
+
optional_parameter :eval # i.e. Kernel#eval
|
64
|
+
end
|
71
65
|
}.should raise_error(NameError)
|
72
66
|
end
|
73
67
|
|
@@ -79,13 +73,9 @@ describe BinData::Base, "with parameters" do
|
|
79
73
|
end
|
80
74
|
|
81
75
|
describe BinData::Base, "with mandatory parameters" do
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
mandatory_parameter :p1
|
86
|
-
mandatory_parameter :p2
|
87
|
-
end
|
88
|
-
END
|
76
|
+
class MandatoryBase < BaseStub
|
77
|
+
mandatory_parameter :p1
|
78
|
+
mandatory_parameter :p2
|
89
79
|
end
|
90
80
|
|
91
81
|
it "should ensure that all mandatory parameters are present" do
|
@@ -104,12 +94,8 @@ describe BinData::Base, "with mandatory parameters" do
|
|
104
94
|
end
|
105
95
|
|
106
96
|
describe BinData::Base, "with default parameters" do
|
107
|
-
|
108
|
-
|
109
|
-
class DefaultBase < BaseStub
|
110
|
-
default_parameter :p1 => "a"
|
111
|
-
end
|
112
|
-
END
|
97
|
+
class DefaultBase < BaseStub
|
98
|
+
default_parameter :p1 => "a"
|
113
99
|
end
|
114
100
|
|
115
101
|
it "should use default parameters when not specified" do
|
@@ -126,13 +112,9 @@ describe BinData::Base, "with default parameters" do
|
|
126
112
|
end
|
127
113
|
|
128
114
|
describe BinData::Base, "with mutually exclusive parameters" do
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
optional_parameters :p1, :p2
|
133
|
-
mutually_exclusive_parameters :p1, :p2
|
134
|
-
end
|
135
|
-
END
|
115
|
+
class MutexParamBase < BaseStub
|
116
|
+
optional_parameters :p1, :p2
|
117
|
+
mutually_exclusive_parameters :p1, :p2
|
136
118
|
end
|
137
119
|
|
138
120
|
it "should not fail when neither of those parameters are present" do
|
@@ -150,14 +132,10 @@ describe BinData::Base, "with mutually exclusive parameters" do
|
|
150
132
|
end
|
151
133
|
|
152
134
|
describe BinData::Base, "with multiple parameters" do
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
optional_parameter :p2
|
158
|
-
default_parameter :p3 => 3
|
159
|
-
end
|
160
|
-
END
|
135
|
+
class WithParamBase < BaseStub
|
136
|
+
mandatory_parameter :p1
|
137
|
+
optional_parameter :p2
|
138
|
+
default_parameter :p3 => 3
|
161
139
|
end
|
162
140
|
|
163
141
|
it "should identify internally accepted parameters" do
|
@@ -220,16 +198,12 @@ describe BinData::Base, "with multiple parameters" do
|
|
220
198
|
end
|
221
199
|
|
222
200
|
describe BinData::Base, "with :check_offset" do
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
super(io)
|
230
|
-
end
|
231
|
-
end
|
232
|
-
END
|
201
|
+
class TenByteOffsetBase < BaseStub
|
202
|
+
def do_read(io)
|
203
|
+
# advance the io position before checking offset
|
204
|
+
io.seekbytes(10)
|
205
|
+
super(io)
|
206
|
+
end
|
233
207
|
end
|
234
208
|
|
235
209
|
before(:each) do
|
@@ -262,16 +236,12 @@ describe BinData::Base, "with :check_offset" do
|
|
262
236
|
end
|
263
237
|
|
264
238
|
describe BinData::Base, "with :adjust_offset" do
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
super(io)
|
272
|
-
end
|
273
|
-
end
|
274
|
-
END
|
239
|
+
class TenByteAdjustingOffsetBase < BaseStub
|
240
|
+
def do_read(io)
|
241
|
+
# advance the io position before checking offset
|
242
|
+
io.seekbytes(10)
|
243
|
+
super(io)
|
244
|
+
end
|
275
245
|
end
|
276
246
|
|
277
247
|
before(:each) do
|