bindata 2.4.15 → 2.5.1
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.
- checksums.yaml +4 -4
- data/ChangeLog.rdoc +16 -0
- data/README.md +7 -10
- data/bindata.gemspec +5 -4
- data/examples/list.rb +1 -1
- data/lib/bindata/alignment.rb +15 -7
- data/lib/bindata/array.rb +54 -54
- data/lib/bindata/base.rb +14 -25
- data/lib/bindata/base_primitive.rb +24 -20
- data/lib/bindata/bits.rb +5 -5
- data/lib/bindata/buffer.rb +89 -11
- data/lib/bindata/choice.rb +9 -6
- data/lib/bindata/count_bytes_remaining.rb +1 -1
- data/lib/bindata/delayed_io.rb +10 -10
- data/lib/bindata/dsl.rb +34 -32
- data/lib/bindata/float.rb +3 -3
- data/lib/bindata/framework.rb +8 -10
- data/lib/bindata/int.rb +9 -9
- data/lib/bindata/io.rb +276 -253
- data/lib/bindata/name.rb +1 -1
- data/lib/bindata/params.rb +9 -7
- data/lib/bindata/primitive.rb +3 -3
- data/lib/bindata/registry.rb +46 -51
- data/lib/bindata/rest.rb +1 -1
- data/lib/bindata/sanitize.rb +9 -16
- data/lib/bindata/section.rb +97 -0
- data/lib/bindata/skip.rb +140 -51
- data/lib/bindata/string.rb +9 -9
- data/lib/bindata/stringz.rb +12 -10
- data/lib/bindata/struct.rb +83 -66
- data/lib/bindata/trace.rb +35 -42
- data/lib/bindata/transform/brotli.rb +35 -0
- data/lib/bindata/transform/lz4.rb +35 -0
- data/lib/bindata/transform/lzma.rb +35 -0
- data/lib/bindata/transform/xor.rb +19 -0
- data/lib/bindata/transform/xz.rb +35 -0
- data/lib/bindata/transform/zlib.rb +33 -0
- data/lib/bindata/transform/zstd.rb +35 -0
- data/lib/bindata/uint8_array.rb +2 -2
- data/lib/bindata/version.rb +1 -1
- data/lib/bindata/virtual.rb +4 -7
- data/lib/bindata/warnings.rb +1 -1
- data/lib/bindata.rb +3 -2
- data/test/array_test.rb +10 -8
- data/test/buffer_test.rb +9 -0
- data/test/choice_test.rb +1 -1
- data/test/delayed_io_test.rb +16 -0
- data/test/io_test.rb +54 -246
- data/test/registry_test.rb +1 -1
- data/test/section_test.rb +111 -0
- data/test/skip_test.rb +55 -10
- data/test/string_test.rb +4 -4
- data/test/stringz_test.rb +8 -0
- data/test/struct_test.rb +87 -12
- data/test/system_test.rb +119 -1
- data/test/test_helper.rb +30 -15
- data/test/warnings_test.rb +12 -0
- metadata +20 -18
- data/lib/bindata/offset.rb +0 -94
- data/test/offset_test.rb +0 -100
data/lib/bindata/struct.rb
CHANGED
@@ -2,7 +2,6 @@ require 'bindata/base'
|
|
2
2
|
require 'bindata/delayed_io'
|
3
3
|
|
4
4
|
module BinData
|
5
|
-
|
6
5
|
class Base
|
7
6
|
optional_parameter :onlyif, :byte_align # Used by Struct
|
8
7
|
end
|
@@ -66,16 +65,18 @@ module BinData
|
|
66
65
|
RESERVED =
|
67
66
|
Hash[*
|
68
67
|
(Hash.instance_methods +
|
69
|
-
%w
|
68
|
+
%w[alias and begin break case class def defined do else elsif
|
70
69
|
end ensure false for if in module next nil not or redo
|
71
70
|
rescue retry return self super then true undef unless until
|
72
|
-
when while yield
|
73
|
-
%w
|
74
|
-
%w
|
75
|
-
%w
|
76
|
-
%w
|
77
|
-
%w
|
78
|
-
|
71
|
+
when while yield] +
|
72
|
+
%w[array element index value] +
|
73
|
+
%w[type initial_length read_until] +
|
74
|
+
%w[fields endian search_prefix hide onlyif byte_align] +
|
75
|
+
%w[choices selection copy_on_change] +
|
76
|
+
%w[read_abs_offset struct_params])
|
77
|
+
.collect(&:to_sym)
|
78
|
+
.uniq.collect { |key| [key, true] }
|
79
|
+
.flatten
|
79
80
|
]
|
80
81
|
|
81
82
|
def initialize_shared_instance
|
@@ -90,11 +91,11 @@ module BinData
|
|
90
91
|
@field_objs = []
|
91
92
|
end
|
92
93
|
|
93
|
-
def clear
|
94
|
-
@field_objs.each { |f| f.
|
94
|
+
def clear # :nodoc:
|
95
|
+
@field_objs.each { |f| f.nil? || f.clear }
|
95
96
|
end
|
96
97
|
|
97
|
-
def clear?
|
98
|
+
def clear? # :nodoc:
|
98
99
|
@field_objs.all? { |f| f.nil? || f.clear? }
|
99
100
|
end
|
100
101
|
|
@@ -124,28 +125,28 @@ module BinData
|
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
127
|
-
def debug_name_of(child)
|
128
|
+
def debug_name_of(child) # :nodoc:
|
128
129
|
field_name = @field_names[find_index_of(child)]
|
129
130
|
"#{debug_name}.#{field_name}"
|
130
131
|
end
|
131
132
|
|
132
|
-
def offset_of(child)
|
133
|
+
def offset_of(child) # :nodoc:
|
133
134
|
instantiate_all_objs
|
134
135
|
sum = sum_num_bytes_below_index(find_index_of(child))
|
135
136
|
child.bit_aligned? ? sum.floor : sum.ceil
|
136
137
|
end
|
137
138
|
|
138
|
-
def do_read(io)
|
139
|
+
def do_read(io) # :nodoc:
|
139
140
|
instantiate_all_objs
|
140
141
|
@field_objs.each { |f| f.do_read(io) if include_obj_for_io?(f) }
|
141
142
|
end
|
142
143
|
|
143
|
-
def do_write(io)
|
144
|
+
def do_write(io) # :nodoc:
|
144
145
|
instantiate_all_objs
|
145
146
|
@field_objs.each { |f| f.do_write(io) if include_obj_for_io?(f) }
|
146
147
|
end
|
147
148
|
|
148
|
-
def do_num_bytes
|
149
|
+
def do_num_bytes # :nodoc:
|
149
150
|
instantiate_all_objs
|
150
151
|
sum_num_bytes_for_all_fields
|
151
152
|
end
|
@@ -155,19 +156,28 @@ module BinData
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def []=(key, value)
|
158
|
-
|
159
|
-
if obj
|
160
|
-
obj.assign(value)
|
161
|
-
end
|
159
|
+
find_obj_for_name(key)&.assign(value)
|
162
160
|
end
|
163
161
|
|
164
162
|
def key?(key)
|
165
163
|
@field_names.index(base_field_name(key))
|
166
164
|
end
|
167
165
|
|
168
|
-
|
169
|
-
|
170
|
-
|
166
|
+
# Calls the given block for each field_name-field_obj pair.
|
167
|
+
#
|
168
|
+
# Does not include anonymous or hidden fields unless
|
169
|
+
# +include_all+ is true.
|
170
|
+
def each_pair(include_all = false)
|
171
|
+
instantiate_all_objs
|
172
|
+
|
173
|
+
pairs = @field_names.zip(@field_objs).select do |name, _obj|
|
174
|
+
name || include_all
|
175
|
+
end
|
176
|
+
|
177
|
+
if block_given?
|
178
|
+
pairs.each { |el| yield(el) }
|
179
|
+
else
|
180
|
+
pairs.each
|
171
181
|
end
|
172
182
|
end
|
173
183
|
|
@@ -205,8 +215,6 @@ module BinData
|
|
205
215
|
if index
|
206
216
|
instantiate_obj_at(index)
|
207
217
|
@field_objs[index]
|
208
|
-
else
|
209
|
-
nil
|
210
218
|
end
|
211
219
|
end
|
212
220
|
|
@@ -243,7 +251,7 @@ module BinData
|
|
243
251
|
{}
|
244
252
|
else
|
245
253
|
hash = Snapshot.new
|
246
|
-
val.each_pair { |k,v| hash[k] = v }
|
254
|
+
val.each_pair { |k, v| hash[k] = v }
|
247
255
|
hash
|
248
256
|
end
|
249
257
|
end
|
@@ -275,12 +283,12 @@ module BinData
|
|
275
283
|
end
|
276
284
|
|
277
285
|
# A hash that can be accessed via attributes.
|
278
|
-
class Snapshot < ::Hash
|
286
|
+
class Snapshot < ::Hash # :nodoc:
|
279
287
|
def []=(key, value)
|
280
288
|
super unless value.nil?
|
281
289
|
end
|
282
290
|
|
283
|
-
def
|
291
|
+
def respond_to_missing?(symbol, include_all = false)
|
284
292
|
key?(symbol) || super
|
285
293
|
end
|
286
294
|
|
@@ -288,60 +296,71 @@ module BinData
|
|
288
296
|
key?(symbol) ? self[symbol] : super
|
289
297
|
end
|
290
298
|
end
|
291
|
-
end
|
292
299
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
+
# Align fields to a multiple of :byte_align
|
301
|
+
module ByteAlignPlugin
|
302
|
+
def do_read(io)
|
303
|
+
offset = 0
|
304
|
+
instantiate_all_objs
|
305
|
+
@field_objs.each do |f|
|
306
|
+
next unless include_obj?(f)
|
307
|
+
|
300
308
|
if align_obj?(f)
|
301
|
-
|
309
|
+
nbytes = bytes_to_align(f, offset.ceil)
|
310
|
+
offset = offset.ceil + nbytes
|
311
|
+
io.readbytes(nbytes)
|
302
312
|
end
|
313
|
+
|
303
314
|
f.do_read(io)
|
315
|
+
nbytes = f.do_num_bytes
|
316
|
+
offset = (nbytes.is_a?(Integer) ? offset.ceil : offset) + nbytes
|
304
317
|
end
|
305
318
|
end
|
306
|
-
end
|
307
319
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
320
|
+
def do_write(io)
|
321
|
+
offset = 0
|
322
|
+
instantiate_all_objs
|
323
|
+
@field_objs.each do |f|
|
324
|
+
next unless include_obj?(f)
|
325
|
+
|
313
326
|
if align_obj?(f)
|
314
|
-
|
327
|
+
nbytes = bytes_to_align(f, offset.ceil)
|
328
|
+
offset = offset.ceil + nbytes
|
329
|
+
io.writebytes("\x00" * nbytes)
|
315
330
|
end
|
331
|
+
|
316
332
|
f.do_write(io)
|
333
|
+
nbytes = f.do_num_bytes
|
334
|
+
offset = (nbytes.is_a?(Integer) ? offset.ceil : offset) + nbytes
|
317
335
|
end
|
318
336
|
end
|
319
|
-
end
|
320
337
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
338
|
+
def sum_num_bytes_below_index(index)
|
339
|
+
sum = 0
|
340
|
+
@field_objs.each_with_index do |obj, i|
|
341
|
+
next unless include_obj?(obj)
|
342
|
+
|
343
|
+
if align_obj?(obj)
|
344
|
+
sum = sum.ceil + bytes_to_align(obj, sum.ceil)
|
345
|
+
end
|
327
346
|
|
328
347
|
break if i >= index
|
329
348
|
|
330
349
|
nbytes = obj.do_num_bytes
|
331
350
|
sum = (nbytes.is_a?(Integer) ? sum.ceil : sum) + nbytes
|
332
351
|
end
|
333
|
-
end
|
334
352
|
|
335
|
-
|
336
|
-
|
353
|
+
sum
|
354
|
+
end
|
337
355
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
356
|
+
def bytes_to_align(obj, rel_offset)
|
357
|
+
align = obj.eval_parameter(:byte_align)
|
358
|
+
(align - (rel_offset % align)) % align
|
359
|
+
end
|
342
360
|
|
343
|
-
|
344
|
-
|
361
|
+
def align_obj?(obj)
|
362
|
+
obj.has_parameter?(:byte_align)
|
363
|
+
end
|
345
364
|
end
|
346
365
|
end
|
347
366
|
|
@@ -362,13 +381,11 @@ module BinData
|
|
362
381
|
|
363
382
|
def sanitize_search_prefix(params)
|
364
383
|
params.sanitize(:search_prefix) do |sprefix|
|
365
|
-
search_prefix =
|
366
|
-
|
367
|
-
prefix = prefix.to_s.chomp("_")
|
368
|
-
search_prefix << prefix if prefix != ""
|
384
|
+
search_prefix = Array(sprefix).collect do |prefix|
|
385
|
+
prefix.to_s.chomp("_")
|
369
386
|
end
|
370
387
|
|
371
|
-
search_prefix
|
388
|
+
search_prefix - [""]
|
372
389
|
end
|
373
390
|
end
|
374
391
|
|
data/lib/bindata/trace.rb
CHANGED
@@ -1,8 +1,26 @@
|
|
1
1
|
module BinData
|
2
|
+
|
3
|
+
# Turn on trace information when reading a BinData object.
|
4
|
+
# If +block+ is given then the tracing only occurs for that block.
|
5
|
+
# This is useful for debugging a BinData declaration.
|
6
|
+
def trace_reading(io = STDERR)
|
7
|
+
@tracer = Tracer.new(io)
|
8
|
+
[BasePrimitive, Choice].each(&:turn_on_tracing)
|
9
|
+
|
10
|
+
if block_given?
|
11
|
+
begin
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
[BasePrimitive, Choice].each(&:turn_off_tracing)
|
15
|
+
@tracer = nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
2
20
|
# reference to the current tracer
|
3
21
|
@tracer ||= nil
|
4
22
|
|
5
|
-
class Tracer
|
23
|
+
class Tracer # :nodoc:
|
6
24
|
def initialize(io)
|
7
25
|
@trace_io = io
|
8
26
|
end
|
@@ -20,47 +38,34 @@ module BinData
|
|
20
38
|
end
|
21
39
|
end
|
22
40
|
|
23
|
-
|
24
|
-
|
25
|
-
# This is useful for debugging a BinData declaration.
|
26
|
-
def trace_reading(io = STDERR)
|
27
|
-
@tracer = Tracer.new(io)
|
28
|
-
[BasePrimitive, Choice].each(&:turn_on_tracing)
|
29
|
-
|
30
|
-
if block_given?
|
31
|
-
begin
|
32
|
-
yield
|
33
|
-
ensure
|
34
|
-
[BasePrimitive, Choice].each(&:turn_off_tracing)
|
35
|
-
@tracer = nil
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def trace_message #:nodoc:
|
41
|
-
yield @tracer if @tracer
|
41
|
+
def trace_message # :nodoc:
|
42
|
+
yield @tracer
|
42
43
|
end
|
43
44
|
|
44
45
|
module_function :trace_reading, :trace_message
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
module TraceHook
|
48
|
+
def turn_on_tracing
|
49
|
+
if !method_defined? :do_read_without_hook
|
49
50
|
alias_method :do_read_without_hook, :do_read
|
50
51
|
alias_method :do_read, :do_read_with_hook
|
51
52
|
end
|
53
|
+
end
|
52
54
|
|
53
|
-
|
55
|
+
def turn_off_tracing
|
56
|
+
if method_defined? :do_read_without_hook
|
54
57
|
alias_method :do_read, :do_read_without_hook
|
58
|
+
remove_method :do_read_without_hook
|
55
59
|
end
|
56
60
|
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class BasePrimitive < BinData::Base
|
64
|
+
extend TraceHook
|
57
65
|
|
58
66
|
def do_read_with_hook(io)
|
59
67
|
do_read_without_hook(io)
|
60
|
-
trace_value
|
61
|
-
end
|
62
68
|
|
63
|
-
def trace_value
|
64
69
|
BinData.trace_message do |tracer|
|
65
70
|
value_string = _value.inspect
|
66
71
|
tracer.trace_obj(debug_name, value_string)
|
@@ -69,27 +74,15 @@ module BinData
|
|
69
74
|
end
|
70
75
|
|
71
76
|
class Choice < BinData::Base
|
72
|
-
|
73
|
-
def turn_on_tracing
|
74
|
-
alias_method :do_read_without_hook, :do_read
|
75
|
-
alias_method :do_read, :do_read_with_hook
|
76
|
-
end
|
77
|
-
|
78
|
-
def turn_off_tracing
|
79
|
-
alias_method :do_read, :do_read_without_hook
|
80
|
-
end
|
81
|
-
end
|
77
|
+
extend TraceHook
|
82
78
|
|
83
79
|
def do_read_with_hook(io)
|
84
|
-
trace_selection
|
85
|
-
do_read_without_hook(io)
|
86
|
-
end
|
87
|
-
|
88
|
-
def trace_selection
|
89
80
|
BinData.trace_message do |tracer|
|
90
81
|
selection_string = eval_parameter(:selection).inspect
|
91
82
|
tracer.trace_obj("#{debug_name}-selection-", selection_string)
|
92
83
|
end
|
84
|
+
|
85
|
+
do_read_without_hook(io)
|
93
86
|
end
|
94
87
|
end
|
95
88
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'brotli'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a brotli compressed data stream.
|
6
|
+
#
|
7
|
+
# gem install brotli
|
8
|
+
class Brotli < BinData::IO::Transform
|
9
|
+
transform_changes_stream_length!
|
10
|
+
|
11
|
+
def initialize(read_length)
|
12
|
+
super()
|
13
|
+
@length = read_length
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(n)
|
17
|
+
@read ||= ::Brotli::inflate(chain_read(@length))
|
18
|
+
@read.slice!(0...n)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(data)
|
22
|
+
@write ||= create_empty_binary_string
|
23
|
+
@write << data
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_read_transform
|
27
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_write_transform
|
31
|
+
chain_write(::Brotli::deflate(@write))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'extlz4'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a LZ4 compressed data stream.
|
6
|
+
#
|
7
|
+
# gem install extlz4
|
8
|
+
class LZ4 < BinData::IO::Transform
|
9
|
+
transform_changes_stream_length!
|
10
|
+
|
11
|
+
def initialize(read_length)
|
12
|
+
super()
|
13
|
+
@length = read_length
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(n)
|
17
|
+
@read ||= ::LZ4::decode(chain_read(@length))
|
18
|
+
@read.slice!(0...n)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(data)
|
22
|
+
@write ||= create_empty_binary_string
|
23
|
+
@write << data
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_read_transform
|
27
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_write_transform
|
31
|
+
chain_write(::LZ4::encode(@write))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'xz'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a lzma compressed data stream.
|
6
|
+
#
|
7
|
+
# gem install ruby-xz
|
8
|
+
class Lzma < BinData::IO::Transform
|
9
|
+
transform_changes_stream_length!
|
10
|
+
|
11
|
+
def initialize(read_length)
|
12
|
+
super()
|
13
|
+
@length = read_length
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(n)
|
17
|
+
@read ||= ::XZ::decompress(chain_read(@length))
|
18
|
+
@read.slice!(0...n)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(data)
|
22
|
+
@write ||= create_empty_binary_string
|
23
|
+
@write << data
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_read_transform
|
27
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_write_transform
|
31
|
+
chain_write(::XZ::compress(@write))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BinData
|
2
|
+
module Transform
|
3
|
+
# Transforms the data stream by xoring each byte.
|
4
|
+
class Xor < BinData::IO::Transform
|
5
|
+
def initialize(xor)
|
6
|
+
super()
|
7
|
+
@xor = xor
|
8
|
+
end
|
9
|
+
|
10
|
+
def read(n)
|
11
|
+
chain_read(n).bytes.map { |byte| (byte ^ @xor).chr }.join
|
12
|
+
end
|
13
|
+
|
14
|
+
def write(data)
|
15
|
+
chain_write(data.bytes.map { |byte| (byte ^ @xor).chr }.join)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'xz'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a xz compressed data stream.
|
6
|
+
#
|
7
|
+
# gem install ruby-xz
|
8
|
+
class XZ < BinData::IO::Transform
|
9
|
+
transform_changes_stream_length!
|
10
|
+
|
11
|
+
def initialize(read_length)
|
12
|
+
super()
|
13
|
+
@length = read_length
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(n)
|
17
|
+
@read ||= ::XZ::decompress(chain_read(@length))
|
18
|
+
@read.slice!(0...n)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(data)
|
22
|
+
@write ||= create_empty_binary_string
|
23
|
+
@write << data
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_read_transform
|
27
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_write_transform
|
31
|
+
chain_write(::XZ::compress(@write))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a zlib compressed data stream.
|
6
|
+
class Zlib < BinData::IO::Transform
|
7
|
+
transform_changes_stream_length!
|
8
|
+
|
9
|
+
def initialize(read_length)
|
10
|
+
super()
|
11
|
+
@length = read_length
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(n)
|
15
|
+
@read ||= ::Zlib::Inflate.inflate(chain_read(@length))
|
16
|
+
@read.slice!(0...n)
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(data)
|
20
|
+
@write ||= create_empty_binary_string
|
21
|
+
@write << data
|
22
|
+
end
|
23
|
+
|
24
|
+
def after_read_transform
|
25
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
def after_write_transform
|
29
|
+
chain_write(::Zlib::Deflate.deflate(@write))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'zstd-ruby'
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
module Transform
|
5
|
+
# Transforms a zstd compressed data stream.
|
6
|
+
#
|
7
|
+
# gem install zstd-ruby
|
8
|
+
class Zstd < BinData::IO::Transform
|
9
|
+
transform_changes_stream_length!
|
10
|
+
|
11
|
+
def initialize(read_length)
|
12
|
+
super()
|
13
|
+
@length = read_length
|
14
|
+
end
|
15
|
+
|
16
|
+
def read(n)
|
17
|
+
@read ||= ::Zstd::decompress(chain_read(@length))
|
18
|
+
@read.slice!(0...n)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(data)
|
22
|
+
@write ||= create_empty_binary_string
|
23
|
+
@write << data
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_read_transform
|
27
|
+
raise IOError, "didn't read all data" unless @read.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_write_transform
|
31
|
+
chain_write(::Zstd::compress(@write))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/bindata/uint8_array.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'bindata/base_primitive'
|
2
2
|
|
3
3
|
module BinData
|
4
4
|
# Uint8Array is a specialised type of array that only contains
|
@@ -49,7 +49,7 @@ module BinData
|
|
49
49
|
end
|
50
50
|
|
51
51
|
class Uint8ArrayArgProcessor < BaseArgProcessor
|
52
|
-
def sanitize_parameters!(obj_class, params)
|
52
|
+
def sanitize_parameters!(obj_class, params) # :nodoc:
|
53
53
|
# ensure one of :initial_length and :read_until exists
|
54
54
|
unless params.has_at_least_one_of?(:initial_length, :read_until)
|
55
55
|
params[:initial_length] = 0
|
data/lib/bindata/version.rb
CHANGED
data/lib/bindata/virtual.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'bindata/base'
|
2
2
|
|
3
3
|
module BinData
|
4
4
|
# A virtual field is one that is neither read, written nor occupies space in
|
@@ -15,7 +15,7 @@ module BinData
|
|
15
15
|
#
|
16
16
|
# obj = A.read("abcdeabcde")
|
17
17
|
# obj.a #=> "abcde"
|
18
|
-
# obj.c.
|
18
|
+
# obj.c.rel_offset #=> 10
|
19
19
|
#
|
20
20
|
# obj = A.read("abcdeABCDE") #=> BinData::ValidityError: assertion failed for obj.c
|
21
21
|
#
|
@@ -29,12 +29,9 @@ module BinData
|
|
29
29
|
# [<tt>:value</tt>] The virtual object will always have this value.
|
30
30
|
#
|
31
31
|
class Virtual < BinData::BasePrimitive
|
32
|
+
def do_read(io); end
|
32
33
|
|
33
|
-
def
|
34
|
-
end
|
35
|
-
|
36
|
-
def do_write(io)
|
37
|
-
end
|
34
|
+
def do_write(io); end
|
38
35
|
|
39
36
|
def do_num_bytes
|
40
37
|
0.0
|
data/lib/bindata/warnings.rb
CHANGED
@@ -13,7 +13,7 @@ module BinData
|
|
13
13
|
owner = method(:initialize).owner
|
14
14
|
if owner != BinData::Base
|
15
15
|
msg = "Don't override #initialize on #{owner}."
|
16
|
-
if %w
|
16
|
+
if %w[BinData::Base BinData::BasePrimitive].include? self.class.superclass.name
|
17
17
|
msg += "\nrename #initialize to #initialize_instance."
|
18
18
|
end
|
19
19
|
fail msg
|