bindata 2.4.10 → 2.5.0
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 +39 -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 +15 -15
- 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 +18 -10
- data/lib/bindata/dsl.rb +37 -35
- data/lib/bindata/float.rb +3 -3
- data/lib/bindata/framework.rb +8 -10
- data/lib/bindata/int.rb +14 -16
- 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 +92 -68
- 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/alignment_test.rb +8 -8
- data/test/array_test.rb +98 -96
- data/test/base_primitive_test.rb +47 -47
- data/test/base_test.rb +24 -24
- data/test/bits_test.rb +15 -15
- data/test/buffer_test.rb +31 -22
- data/test/choice_test.rb +32 -32
- data/test/count_bytes_remaining_test.rb +8 -8
- data/test/delayed_io_test.rb +91 -30
- data/test/float_test.rb +8 -8
- data/test/int_test.rb +14 -14
- data/test/io_test.rb +110 -302
- data/test/lazy_test.rb +38 -38
- data/test/params_test.rb +19 -19
- data/test/primitive_test.rb +26 -26
- data/test/record_test.rb +99 -99
- data/test/registry_test.rb +43 -43
- data/test/rest_test.rb +5 -5
- data/test/section_test.rb +111 -0
- data/test/skip_test.rb +71 -26
- data/test/string_test.rb +60 -60
- data/test/stringz_test.rb +34 -26
- data/test/struct_test.rb +167 -92
- data/test/system_test.rb +159 -41
- data/test/test_helper.rb +24 -13
- data/test/uint8_array_test.rb +6 -6
- data/test/virtual_test.rb +7 -7
- data/test/warnings_test.rb +14 -2
- 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
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'bindata/base'
|
2
|
+
require 'bindata/delayed_io'
|
2
3
|
|
3
4
|
module BinData
|
4
|
-
|
5
5
|
class Base
|
6
6
|
optional_parameter :onlyif, :byte_align # Used by Struct
|
7
7
|
end
|
@@ -65,16 +65,18 @@ module BinData
|
|
65
65
|
RESERVED =
|
66
66
|
Hash[*
|
67
67
|
(Hash.instance_methods +
|
68
|
-
%w
|
68
|
+
%w[alias and begin break case class def defined do else elsif
|
69
69
|
end ensure false for if in module next nil not or redo
|
70
70
|
rescue retry return self super then true undef unless until
|
71
|
-
when while yield
|
72
|
-
%w
|
73
|
-
%w
|
74
|
-
%w
|
75
|
-
%w
|
76
|
-
%w
|
77
|
-
|
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
|
78
80
|
]
|
79
81
|
|
80
82
|
def initialize_shared_instance
|
@@ -89,11 +91,11 @@ module BinData
|
|
89
91
|
@field_objs = []
|
90
92
|
end
|
91
93
|
|
92
|
-
def clear
|
93
|
-
@field_objs.each { |f| f.
|
94
|
+
def clear # :nodoc:
|
95
|
+
@field_objs.each { |f| f.nil? || f.clear }
|
94
96
|
end
|
95
97
|
|
96
|
-
def clear?
|
98
|
+
def clear? # :nodoc:
|
97
99
|
@field_objs.all? { |f| f.nil? || f.clear? }
|
98
100
|
end
|
99
101
|
|
@@ -123,28 +125,28 @@ module BinData
|
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
126
|
-
def debug_name_of(child)
|
128
|
+
def debug_name_of(child) # :nodoc:
|
127
129
|
field_name = @field_names[find_index_of(child)]
|
128
130
|
"#{debug_name}.#{field_name}"
|
129
131
|
end
|
130
132
|
|
131
|
-
def offset_of(child)
|
133
|
+
def offset_of(child) # :nodoc:
|
132
134
|
instantiate_all_objs
|
133
135
|
sum = sum_num_bytes_below_index(find_index_of(child))
|
134
136
|
child.bit_aligned? ? sum.floor : sum.ceil
|
135
137
|
end
|
136
138
|
|
137
|
-
def do_read(io)
|
139
|
+
def do_read(io) # :nodoc:
|
138
140
|
instantiate_all_objs
|
139
|
-
@field_objs.each { |f| f.do_read(io) if
|
141
|
+
@field_objs.each { |f| f.do_read(io) if include_obj_for_io?(f) }
|
140
142
|
end
|
141
143
|
|
142
|
-
def do_write(io)
|
144
|
+
def do_write(io) # :nodoc:
|
143
145
|
instantiate_all_objs
|
144
|
-
@field_objs.each { |f| f.do_write(io) if
|
146
|
+
@field_objs.each { |f| f.do_write(io) if include_obj_for_io?(f) }
|
145
147
|
end
|
146
148
|
|
147
|
-
def do_num_bytes
|
149
|
+
def do_num_bytes # :nodoc:
|
148
150
|
instantiate_all_objs
|
149
151
|
sum_num_bytes_for_all_fields
|
150
152
|
end
|
@@ -154,19 +156,28 @@ module BinData
|
|
154
156
|
end
|
155
157
|
|
156
158
|
def []=(key, value)
|
157
|
-
|
158
|
-
if obj
|
159
|
-
obj.assign(value)
|
160
|
-
end
|
159
|
+
find_obj_for_name(key)&.assign(value)
|
161
160
|
end
|
162
161
|
|
163
162
|
def key?(key)
|
164
163
|
@field_names.index(base_field_name(key))
|
165
164
|
end
|
166
165
|
|
167
|
-
|
168
|
-
|
169
|
-
|
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
|
170
181
|
end
|
171
182
|
end
|
172
183
|
|
@@ -204,8 +215,6 @@ module BinData
|
|
204
215
|
if index
|
205
216
|
instantiate_obj_at(index)
|
206
217
|
@field_objs[index]
|
207
|
-
else
|
208
|
-
nil
|
209
218
|
end
|
210
219
|
end
|
211
220
|
|
@@ -242,7 +251,7 @@ module BinData
|
|
242
251
|
{}
|
243
252
|
else
|
244
253
|
hash = Snapshot.new
|
245
|
-
val.each_pair { |k,v| hash[k] = v }
|
254
|
+
val.each_pair { |k, v| hash[k] = v }
|
246
255
|
hash
|
247
256
|
end
|
248
257
|
end
|
@@ -263,17 +272,23 @@ module BinData
|
|
263
272
|
end
|
264
273
|
end
|
265
274
|
|
275
|
+
def include_obj_for_io?(obj)
|
276
|
+
# Used by #do_read and #do_write, to ensure the stream is passed to
|
277
|
+
# DelayedIO objects for delayed processing.
|
278
|
+
include_obj?(obj) || DelayedIO === obj
|
279
|
+
end
|
280
|
+
|
266
281
|
def include_obj?(obj)
|
267
282
|
!obj.has_parameter?(:onlyif) || obj.eval_parameter(:onlyif)
|
268
283
|
end
|
269
284
|
|
270
285
|
# A hash that can be accessed via attributes.
|
271
|
-
class Snapshot < ::Hash
|
286
|
+
class Snapshot < ::Hash # :nodoc:
|
272
287
|
def []=(key, value)
|
273
288
|
super unless value.nil?
|
274
289
|
end
|
275
290
|
|
276
|
-
def
|
291
|
+
def respond_to_missing?(symbol, include_all = false)
|
277
292
|
key?(symbol) || super
|
278
293
|
end
|
279
294
|
|
@@ -281,60 +296,71 @@ module BinData
|
|
281
296
|
key?(symbol) ? self[symbol] : super
|
282
297
|
end
|
283
298
|
end
|
284
|
-
end
|
285
299
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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
|
+
|
293
308
|
if align_obj?(f)
|
294
|
-
|
309
|
+
nbytes = bytes_to_align(f, offset.ceil)
|
310
|
+
offset = offset.ceil + nbytes
|
311
|
+
io.readbytes(nbytes)
|
295
312
|
end
|
313
|
+
|
296
314
|
f.do_read(io)
|
315
|
+
nbytes = f.do_num_bytes
|
316
|
+
offset = (nbytes.is_a?(Integer) ? offset.ceil : offset) + nbytes
|
297
317
|
end
|
298
318
|
end
|
299
|
-
end
|
300
319
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
+
|
306
326
|
if align_obj?(f)
|
307
|
-
|
327
|
+
nbytes = bytes_to_align(f, offset.ceil)
|
328
|
+
offset = offset.ceil + nbytes
|
329
|
+
io.writebytes("\x00" * nbytes)
|
308
330
|
end
|
331
|
+
|
309
332
|
f.do_write(io)
|
333
|
+
nbytes = f.do_num_bytes
|
334
|
+
offset = (nbytes.is_a?(Integer) ? offset.ceil : offset) + nbytes
|
310
335
|
end
|
311
336
|
end
|
312
|
-
end
|
313
337
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
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
|
320
346
|
|
321
347
|
break if i >= index
|
322
348
|
|
323
349
|
nbytes = obj.do_num_bytes
|
324
350
|
sum = (nbytes.is_a?(Integer) ? sum.ceil : sum) + nbytes
|
325
351
|
end
|
326
|
-
end
|
327
352
|
|
328
|
-
|
329
|
-
|
353
|
+
sum
|
354
|
+
end
|
330
355
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
356
|
+
def bytes_to_align(obj, rel_offset)
|
357
|
+
align = obj.eval_parameter(:byte_align)
|
358
|
+
(align - (rel_offset % align)) % align
|
359
|
+
end
|
335
360
|
|
336
|
-
|
337
|
-
|
361
|
+
def align_obj?(obj)
|
362
|
+
obj.has_parameter?(:byte_align)
|
363
|
+
end
|
338
364
|
end
|
339
365
|
end
|
340
366
|
|
@@ -355,13 +381,11 @@ module BinData
|
|
355
381
|
|
356
382
|
def sanitize_search_prefix(params)
|
357
383
|
params.sanitize(:search_prefix) do |sprefix|
|
358
|
-
search_prefix =
|
359
|
-
|
360
|
-
prefix = prefix.to_s.chomp("_")
|
361
|
-
search_prefix << prefix if prefix != ""
|
384
|
+
search_prefix = Array(sprefix).collect do |prefix|
|
385
|
+
prefix.to_s.chomp("_")
|
362
386
|
end
|
363
387
|
|
364
|
-
search_prefix
|
388
|
+
search_prefix - [""]
|
365
389
|
end
|
366
390
|
end
|
367
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
|