bindata 1.2.1 → 1.2.2
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 +8 -0
- data/Rakefile +2 -1
- data/lib/bindata.rb +1 -1
- data/lib/bindata/array.rb +26 -30
- data/lib/bindata/base.rb +60 -51
- data/lib/bindata/base_primitive.rb +35 -44
- data/lib/bindata/bits.rb +6 -7
- data/lib/bindata/choice.rb +18 -22
- data/lib/bindata/deprecated.rb +42 -0
- data/lib/bindata/dsl.rb +12 -0
- data/lib/bindata/float.rb +1 -1
- data/lib/bindata/int.rb +5 -5
- data/lib/bindata/lazy.rb +2 -2
- data/lib/bindata/primitive.rb +1 -1
- data/lib/bindata/record.rb +25 -0
- data/lib/bindata/string.rb +5 -5
- data/lib/bindata/stringz.rb +5 -5
- data/lib/bindata/struct.rb +29 -33
- data/lib/bindata/wrapper.rb +16 -27
- data/manual.md +1187 -0
- data/spec/base_primitive_spec.rb +6 -14
- data/spec/base_spec.rb +38 -37
- data/spec/deprecated_spec.rb +36 -0
- data/spec/primitive_spec.rb +9 -0
- data/spec/record_spec.rb +11 -0
- data/spec/string_spec.rb +5 -6
- metadata +5 -5
- data/lib/bench.rb +0 -102
data/lib/bindata/choice.rb
CHANGED
@@ -145,6 +145,14 @@ module BinData
|
|
145
145
|
current_choice.clear?
|
146
146
|
end
|
147
147
|
|
148
|
+
def assign(val)
|
149
|
+
current_choice.assign(val)
|
150
|
+
end
|
151
|
+
|
152
|
+
def snapshot
|
153
|
+
current_choice.snapshot
|
154
|
+
end
|
155
|
+
|
148
156
|
def respond_to?(symbol, include_private = false) #:nodoc:
|
149
157
|
current_choice.respond_to?(symbol, include_private) || super
|
150
158
|
end
|
@@ -153,39 +161,27 @@ module BinData
|
|
153
161
|
current_choice.__send__(symbol, *args, &block)
|
154
162
|
end
|
155
163
|
|
156
|
-
|
157
|
-
private
|
158
|
-
|
159
|
-
def _do_read(io)
|
164
|
+
def do_read(io) #:nodoc:
|
160
165
|
trace_selection
|
161
166
|
current_choice.do_read(io)
|
162
167
|
end
|
163
168
|
|
164
|
-
def
|
165
|
-
BinData::trace_message do |tracer|
|
166
|
-
selection_string = eval_parameter(:selection).inspect
|
167
|
-
tracer.trace_obj("#{debug_name}-selection-", selection_string)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def _done_read
|
172
|
-
current_choice.done_read
|
173
|
-
end
|
174
|
-
|
175
|
-
def _do_write(io)
|
169
|
+
def do_write(io) #:nodoc:
|
176
170
|
current_choice.do_write(io)
|
177
171
|
end
|
178
172
|
|
179
|
-
def
|
173
|
+
def do_num_bytes #:nodoc:
|
180
174
|
current_choice.do_num_bytes
|
181
175
|
end
|
182
176
|
|
183
|
-
|
184
|
-
|
185
|
-
end
|
177
|
+
#---------------
|
178
|
+
private
|
186
179
|
|
187
|
-
def
|
188
|
-
|
180
|
+
def trace_selection
|
181
|
+
BinData::trace_message do |tracer|
|
182
|
+
selection_string = eval_parameter(:selection).inspect
|
183
|
+
tracer.trace_obj("#{debug_name}-selection-", selection_string)
|
184
|
+
end
|
189
185
|
end
|
190
186
|
|
191
187
|
def current_choice
|
data/lib/bindata/deprecated.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# Implement Kernel#instance_exec for Ruby 1.8.6 and below
|
2
|
+
unless Object.respond_to? :instance_exec
|
3
|
+
module Kernel
|
4
|
+
# Taken from http://eigenclass.org/hiki/instance_exec
|
5
|
+
def instance_exec(*args, &block)
|
6
|
+
mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
|
7
|
+
Object.class_eval{ define_method(mname, &block) }
|
8
|
+
begin
|
9
|
+
ret = send(mname, *args)
|
10
|
+
ensure
|
11
|
+
Object.class_eval{ undef_method(mname) } rescue nil
|
12
|
+
end
|
13
|
+
ret
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
1
18
|
module BinData
|
2
19
|
class Base
|
3
20
|
class << self
|
@@ -12,6 +29,31 @@ module BinData
|
|
12
29
|
register_class(class_to_register)
|
13
30
|
end
|
14
31
|
end
|
32
|
+
|
33
|
+
def _do_read(io)
|
34
|
+
warn "#{caller[0]} `_do_read(io)' is deprecated as of BinData 1.3.0. Replace with `do_read(io)'"
|
35
|
+
do_read(io)
|
36
|
+
end
|
37
|
+
|
38
|
+
def _do_write(io)
|
39
|
+
warn "#{caller[0]} `_do_write(io)' is deprecated as of BinData 1.3.0. Replace with `do_write(io)'"
|
40
|
+
do_write(io)
|
41
|
+
end
|
42
|
+
|
43
|
+
def _do_num_bytes
|
44
|
+
warn "#{caller[0]} `_do_num_bytes' is deprecated as of BinData 1.3.0. Replace with `do_num_bytes'"
|
45
|
+
do_num_bytes
|
46
|
+
end
|
47
|
+
|
48
|
+
def _assign(val)
|
49
|
+
warn "#{caller[0]} `_assign(val)' is deprecated as of BinData 1.3.0. Replace with `assign(val)'"
|
50
|
+
assign(val)
|
51
|
+
end
|
52
|
+
|
53
|
+
def _snapshot
|
54
|
+
warn "#{caller[0]} `_snapshot' is deprecated as of BinData 1.3.0. Replace with `snapshot'"
|
55
|
+
snapshot
|
56
|
+
end
|
15
57
|
end
|
16
58
|
|
17
59
|
class SingleValue
|
data/lib/bindata/dsl.rb
CHANGED
@@ -23,6 +23,10 @@ module BinData
|
|
23
23
|
def method_missing(symbol, *args, &block) #:nodoc:
|
24
24
|
dsl_parser.__send__(symbol, *args, &block)
|
25
25
|
end
|
26
|
+
|
27
|
+
# Assert object is not an array or string.
|
28
|
+
def to_ary; nil; end
|
29
|
+
def to_str; nil; end
|
26
30
|
end
|
27
31
|
|
28
32
|
# An array containing a field definition of the form
|
@@ -230,6 +234,10 @@ module BinData
|
|
230
234
|
dsl_raise SyntaxError, "field must have a name"
|
231
235
|
end
|
232
236
|
|
237
|
+
if malformed_name?(name)
|
238
|
+
dsl_raise NameError.new("", name), "field '#{name}' is an illegal fieldname"
|
239
|
+
end
|
240
|
+
|
233
241
|
if duplicate_name?(name)
|
234
242
|
dsl_raise SyntaxError, "duplicate field '#{name}'"
|
235
243
|
end
|
@@ -266,6 +274,10 @@ module BinData
|
|
266
274
|
end
|
267
275
|
end
|
268
276
|
|
277
|
+
def malformed_name?(name)
|
278
|
+
name != "" and /^[a-z_]\w*$/ !~ name
|
279
|
+
end
|
280
|
+
|
269
281
|
def duplicate_name?(name)
|
270
282
|
name != "" and fields.field_names.include?(name)
|
271
283
|
end
|
data/lib/bindata/float.rb
CHANGED
data/lib/bindata/int.rb
CHANGED
@@ -31,18 +31,18 @@ module BinData
|
|
31
31
|
raise "nbits must be divisible by 8" unless (nbits % 8).zero?
|
32
32
|
|
33
33
|
int_class.module_eval <<-END
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def _assign(val)
|
34
|
+
def assign(val)
|
38
35
|
#{create_clamp_code(nbits, signed)}
|
39
36
|
super(val)
|
40
37
|
end
|
41
38
|
|
42
|
-
def
|
39
|
+
def do_num_bytes
|
43
40
|
#{nbits / 8}
|
44
41
|
end
|
45
42
|
|
43
|
+
#---------------
|
44
|
+
private
|
45
|
+
|
46
46
|
def sensible_default
|
47
47
|
0
|
48
48
|
end
|
data/lib/bindata/lazy.rb
CHANGED
@@ -51,7 +51,7 @@ module BinData
|
|
51
51
|
if val.is_a? Symbol
|
52
52
|
__send__(val)
|
53
53
|
elsif val.respond_to? :arity
|
54
|
-
|
54
|
+
instance_exec(&val)
|
55
55
|
else
|
56
56
|
val
|
57
57
|
end
|
@@ -117,7 +117,7 @@ module BinData
|
|
117
117
|
if val.is_a?(Symbol)
|
118
118
|
parent.__send__(val, *args)
|
119
119
|
elsif val.respond_to?(:arity)
|
120
|
-
parent.
|
120
|
+
parent.instance_exec(&val)
|
121
121
|
else
|
122
122
|
val
|
123
123
|
end
|
data/lib/bindata/primitive.rb
CHANGED
data/lib/bindata/record.rb
CHANGED
@@ -55,6 +55,31 @@ module BinData
|
|
55
55
|
params[:hide] = hide unless hide.empty?
|
56
56
|
|
57
57
|
super(params, sanitizer)
|
58
|
+
|
59
|
+
define_field_accessors(params[:fields].fields)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Defines accessor methods to avoid the overhead of going through
|
63
|
+
# Struct#method_missing. This is purely a speed optimisation.
|
64
|
+
# Removing this method will not have any effect on correctness.
|
65
|
+
def define_field_accessors(fields) #:nodoc:
|
66
|
+
unless method_defined?(:bindata_defined_accessors_for_fields?)
|
67
|
+
fields.each_with_index do |field, i|
|
68
|
+
name = field.name
|
69
|
+
if name
|
70
|
+
define_method(name.to_sym) do
|
71
|
+
instantiate_obj_at(i) unless @field_objs[i]
|
72
|
+
@field_objs[i]
|
73
|
+
end
|
74
|
+
define_method((name + "=").to_sym) do |*vals|
|
75
|
+
instantiate_obj_at(i) unless @field_objs[i]
|
76
|
+
@field_objs[i].assign(*vals)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
define_method(:bindata_defined_accessors_for_fields?) { true }
|
82
|
+
end
|
58
83
|
end
|
59
84
|
end
|
60
85
|
end
|
data/lib/bindata/string.rb
CHANGED
@@ -77,15 +77,12 @@ module BinData
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def _assign(val)
|
80
|
+
def assign(val)
|
84
81
|
val = val.dup.force_encoding(Encoding::BINARY) if RUBY_VERSION >= "1.9"
|
85
82
|
super(val)
|
86
83
|
end
|
87
84
|
|
88
|
-
def
|
85
|
+
def snapshot
|
89
86
|
# override to ensure length and optionally trim padding
|
90
87
|
result = super
|
91
88
|
if has_parameter?(:length)
|
@@ -97,6 +94,9 @@ module BinData
|
|
97
94
|
result
|
98
95
|
end
|
99
96
|
|
97
|
+
#---------------
|
98
|
+
private
|
99
|
+
|
100
100
|
def truncate_or_pad_to_length(str)
|
101
101
|
len = eval_parameter(:length) || str.length
|
102
102
|
if str.length == len
|
data/lib/bindata/stringz.rb
CHANGED
@@ -31,20 +31,20 @@ module BinData
|
|
31
31
|
|
32
32
|
optional_parameters :max_length
|
33
33
|
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def _assign(val)
|
34
|
+
def assign(val)
|
38
35
|
val = val.dup.force_encoding(Encoding::BINARY) if RUBY_VERSION >= "1.9"
|
39
36
|
super(val)
|
40
37
|
end
|
41
38
|
|
42
|
-
def
|
39
|
+
def snapshot
|
43
40
|
# override to always remove trailing zero bytes
|
44
41
|
result = super
|
45
42
|
trim_and_zero_terminate(result).chomp("\0")
|
46
43
|
end
|
47
44
|
|
45
|
+
#---------------
|
46
|
+
private
|
47
|
+
|
48
48
|
def value_to_binary_string(val)
|
49
49
|
trim_and_zero_terminate(val)
|
50
50
|
end
|
data/lib/bindata/struct.rb
CHANGED
@@ -157,6 +157,20 @@ module BinData
|
|
157
157
|
@field_objs.all? { |f| f.nil? or f.clear? }
|
158
158
|
end
|
159
159
|
|
160
|
+
def assign(val)
|
161
|
+
clear
|
162
|
+
assign_fields(as_snapshot(val))
|
163
|
+
end
|
164
|
+
|
165
|
+
def snapshot
|
166
|
+
snapshot = Snapshot.new
|
167
|
+
field_names.each do |name|
|
168
|
+
obj = find_obj_for_name(name)
|
169
|
+
snapshot[name] = obj.snapshot if include_obj(obj)
|
170
|
+
end
|
171
|
+
snapshot
|
172
|
+
end
|
173
|
+
|
160
174
|
# Returns a list of the names of all fields accessible through this
|
161
175
|
# object. +include_hidden+ specifies whether to include hidden names
|
162
176
|
# in the listing.
|
@@ -193,6 +207,21 @@ module BinData
|
|
193
207
|
child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor
|
194
208
|
end
|
195
209
|
|
210
|
+
def do_read(io) #:nodoc:
|
211
|
+
instantiate_all_objs
|
212
|
+
@field_objs.each { |f| f.do_read(io) if include_obj(f) }
|
213
|
+
end
|
214
|
+
|
215
|
+
def do_write(io) #:nodoc
|
216
|
+
instantiate_all_objs
|
217
|
+
@field_objs.each { |f| f.do_write(io) if include_obj(f) }
|
218
|
+
end
|
219
|
+
|
220
|
+
def do_num_bytes #:nodoc:
|
221
|
+
instantiate_all_objs
|
222
|
+
sum_num_bytes_for_all_fields.ceil
|
223
|
+
end
|
224
|
+
|
196
225
|
#---------------
|
197
226
|
private
|
198
227
|
|
@@ -233,30 +262,6 @@ module BinData
|
|
233
262
|
end
|
234
263
|
end
|
235
264
|
|
236
|
-
def _do_read(io)
|
237
|
-
instantiate_all_objs
|
238
|
-
@field_objs.each { |f| f.do_read(io) if include_obj(f) }
|
239
|
-
end
|
240
|
-
|
241
|
-
def _done_read
|
242
|
-
@field_objs.each { |f| f.done_read if include_obj(f) }
|
243
|
-
end
|
244
|
-
|
245
|
-
def _do_write(io)
|
246
|
-
instantiate_all_objs
|
247
|
-
@field_objs.each { |f| f.do_write(io) if include_obj(f) }
|
248
|
-
end
|
249
|
-
|
250
|
-
def _do_num_bytes
|
251
|
-
instantiate_all_objs
|
252
|
-
sum_num_bytes_for_all_fields.ceil
|
253
|
-
end
|
254
|
-
|
255
|
-
def _assign(val)
|
256
|
-
clear
|
257
|
-
assign_fields(as_snapshot(val))
|
258
|
-
end
|
259
|
-
|
260
265
|
def as_snapshot(val)
|
261
266
|
if val.class == Hash
|
262
267
|
snapshot = Snapshot.new
|
@@ -278,15 +283,6 @@ module BinData
|
|
278
283
|
end
|
279
284
|
end
|
280
285
|
|
281
|
-
def _snapshot
|
282
|
-
snapshot = Snapshot.new
|
283
|
-
field_names.each do |name|
|
284
|
-
obj = find_obj_for_name(name)
|
285
|
-
snapshot[name] = obj.snapshot if include_obj(obj)
|
286
|
-
end
|
287
|
-
snapshot
|
288
|
-
end
|
289
|
-
|
290
286
|
def sum_num_bytes_for_all_fields
|
291
287
|
sum_num_bytes_below_index(@field_objs.length)
|
292
288
|
end
|
data/lib/bindata/wrapper.rb
CHANGED
@@ -48,50 +48,39 @@ module BinData
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def clear #:nodoc:
|
51
|
-
wrapped.clear
|
51
|
+
@wrapped.clear
|
52
52
|
end
|
53
53
|
|
54
54
|
def clear? #:nodoc:
|
55
|
-
wrapped.clear?
|
55
|
+
@wrapped.clear?
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
wrapped.
|
58
|
+
def assign(val)
|
59
|
+
@wrapped.assign(val)
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
63
|
-
wrapped.
|
64
|
-
end
|
65
|
-
|
66
|
-
#---------------
|
67
|
-
private
|
68
|
-
|
69
|
-
def wrapped
|
70
|
-
@wrapped
|
62
|
+
def snapshot
|
63
|
+
@wrapped.snapshot
|
71
64
|
end
|
72
65
|
|
73
|
-
def
|
74
|
-
wrapped.
|
75
|
-
end
|
76
|
-
|
77
|
-
def _done_read
|
78
|
-
wrapped.done_read
|
66
|
+
def respond_to?(symbol, include_private = false) #:nodoc:
|
67
|
+
@wrapped.respond_to?(symbol, include_private) || super
|
79
68
|
end
|
80
69
|
|
81
|
-
def
|
82
|
-
wrapped.
|
70
|
+
def method_missing(symbol, *args, &block) #:nodoc:
|
71
|
+
@wrapped.__send__(symbol, *args, &block)
|
83
72
|
end
|
84
73
|
|
85
|
-
def
|
86
|
-
wrapped.
|
74
|
+
def do_read(io) #:nodoc:
|
75
|
+
@wrapped.do_read(io)
|
87
76
|
end
|
88
77
|
|
89
|
-
def
|
90
|
-
wrapped.
|
78
|
+
def do_write(io) #:nodoc
|
79
|
+
@wrapped.do_write(io)
|
91
80
|
end
|
92
81
|
|
93
|
-
def
|
94
|
-
wrapped.
|
82
|
+
def do_num_bytes #:nodoc:
|
83
|
+
@wrapped.do_num_bytes
|
95
84
|
end
|
96
85
|
end
|
97
86
|
end
|