bindata 2.4.14 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.rdoc +20 -0
- data/LICENSE +25 -0
- data/NEWS.rdoc +5 -0
- data/README.md +6 -9
- data/bindata.gemspec +9 -4
- data/examples/NBT.txt +1 -1
- 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 +12 -11
- 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 +18 -18
- 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 +1 -0
- 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 +24 -13
- data/test/warnings_test.rb +12 -0
- metadata +19 -22
- data/.gitignore +0 -2
- data/.travis.yml +0 -15
- data/BSDL +0 -22
- data/COPYING +0 -52
- data/INSTALL +0 -12
- 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
|