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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.rdoc +16 -0
  3. data/README.md +7 -10
  4. data/bindata.gemspec +5 -4
  5. data/examples/list.rb +1 -1
  6. data/lib/bindata/alignment.rb +15 -7
  7. data/lib/bindata/array.rb +54 -54
  8. data/lib/bindata/base.rb +14 -25
  9. data/lib/bindata/base_primitive.rb +24 -20
  10. data/lib/bindata/bits.rb +5 -5
  11. data/lib/bindata/buffer.rb +89 -11
  12. data/lib/bindata/choice.rb +9 -6
  13. data/lib/bindata/count_bytes_remaining.rb +1 -1
  14. data/lib/bindata/delayed_io.rb +10 -10
  15. data/lib/bindata/dsl.rb +34 -32
  16. data/lib/bindata/float.rb +3 -3
  17. data/lib/bindata/framework.rb +8 -10
  18. data/lib/bindata/int.rb +9 -9
  19. data/lib/bindata/io.rb +276 -253
  20. data/lib/bindata/name.rb +1 -1
  21. data/lib/bindata/params.rb +9 -7
  22. data/lib/bindata/primitive.rb +3 -3
  23. data/lib/bindata/registry.rb +46 -51
  24. data/lib/bindata/rest.rb +1 -1
  25. data/lib/bindata/sanitize.rb +9 -16
  26. data/lib/bindata/section.rb +97 -0
  27. data/lib/bindata/skip.rb +140 -51
  28. data/lib/bindata/string.rb +9 -9
  29. data/lib/bindata/stringz.rb +12 -10
  30. data/lib/bindata/struct.rb +83 -66
  31. data/lib/bindata/trace.rb +35 -42
  32. data/lib/bindata/transform/brotli.rb +35 -0
  33. data/lib/bindata/transform/lz4.rb +35 -0
  34. data/lib/bindata/transform/lzma.rb +35 -0
  35. data/lib/bindata/transform/xor.rb +19 -0
  36. data/lib/bindata/transform/xz.rb +35 -0
  37. data/lib/bindata/transform/zlib.rb +33 -0
  38. data/lib/bindata/transform/zstd.rb +35 -0
  39. data/lib/bindata/uint8_array.rb +2 -2
  40. data/lib/bindata/version.rb +1 -1
  41. data/lib/bindata/virtual.rb +4 -7
  42. data/lib/bindata/warnings.rb +1 -1
  43. data/lib/bindata.rb +3 -2
  44. data/test/array_test.rb +10 -8
  45. data/test/buffer_test.rb +9 -0
  46. data/test/choice_test.rb +1 -1
  47. data/test/delayed_io_test.rb +16 -0
  48. data/test/io_test.rb +54 -246
  49. data/test/registry_test.rb +1 -1
  50. data/test/section_test.rb +111 -0
  51. data/test/skip_test.rb +55 -10
  52. data/test/string_test.rb +4 -4
  53. data/test/stringz_test.rb +8 -0
  54. data/test/struct_test.rb +87 -12
  55. data/test/system_test.rb +119 -1
  56. data/test/test_helper.rb +30 -15
  57. data/test/warnings_test.rb +12 -0
  58. metadata +20 -18
  59. data/lib/bindata/offset.rb +0 -94
  60. data/test/offset_test.rb +0 -100
data/test/string_test.rb CHANGED
@@ -298,15 +298,15 @@ end
298
298
  describe BinData::String, "warnings" do
299
299
  it "warns if has :asserted_value but no :length" do
300
300
  obj = BinData::String.new(asserted_value: "ABC")
301
- obj.must_warn "obj does not have a :read_length parameter - returning empty string" do
301
+ _ {
302
302
  _ { obj.read("abcde") }.must_raise BinData::ValidityError
303
- end
303
+ }.must_warn "obj does not have a :read_length parameter - returning empty string"
304
304
  end
305
305
 
306
306
  it "warns if has :value but no :read_length" do
307
307
  obj = BinData::String.new(value: "ABC")
308
- obj.must_warn "obj does not have a :read_length parameter - returning empty string" do
308
+ _ {
309
309
  obj.read("abcde")
310
- end
310
+ }.must_warn "obj does not have a :read_length parameter - returning empty string"
311
311
  end
312
312
  end
data/test/stringz_test.rb CHANGED
@@ -76,6 +76,14 @@ end
76
76
  describe BinData::Stringz, "with max_length" do
77
77
  let(:obj) { BinData::Stringz.new(max_length: 5) }
78
78
 
79
+ it "fails if max_length is less that 1" do
80
+ obj = BinData::Stringz.new(max_length: 0)
81
+
82
+ _{ obj.read "abc\0" }.must_raise ArgumentError
83
+ _{ obj.to_binary_s }.must_raise ArgumentError
84
+ _{ obj.num_bytes }.must_raise ArgumentError
85
+ end
86
+
79
87
  it "reads less than max_length" do
80
88
  io = StringIO.new("abc\0xyz")
81
89
  obj.read(io)
data/test/struct_test.rb CHANGED
@@ -45,24 +45,65 @@ describe BinData::Struct, "with anonymous fields" do
45
45
  params = { fields: [
46
46
  [:int8, :a, {initial_value: 5}],
47
47
  [:int8, nil],
48
- [:int8, '', {value: :a}]
48
+ [:int8, '', {value: :a}],
49
+ [:int8, :b]
49
50
  ] }
50
51
  BinData::Struct.new(params)
51
52
  }
52
53
 
53
54
  it "only shows non anonymous fields" do
54
- _(obj.field_names).must_equal [:a]
55
+ _(obj.field_names).must_equal [:a, :b]
55
56
  end
56
57
 
57
58
  it "does not include anonymous fields in snapshot" do
58
- obj.a = 5
59
- _(obj.snapshot).must_equal({a: 5})
59
+ obj.a = 6
60
+ _(obj.snapshot).must_equal({a: 6, b: 0})
60
61
  end
61
62
 
62
63
  it "writes anonymous fields" do
63
- obj.read("\001\002\003")
64
+ obj.read("\001\002\003\004")
64
65
  obj.a.clear
65
- _(obj.to_binary_s).must_equal_binary "\005\002\005"
66
+ _(obj.to_binary_s).must_equal_binary "\005\002\005\004"
67
+ end
68
+
69
+ it "does not include anonymous fields in each_pair" do
70
+ _(obj.each_pair.count).must_equal 2
71
+ end
72
+
73
+ it "includes anonymous fields in each_pair when specified" do
74
+ _(obj.each_pair(true).count).must_equal 4
75
+ end
76
+
77
+ it "clears" do
78
+ obj.b = 3
79
+ refute obj.clear?
80
+
81
+ obj.clear
82
+ assert obj.clear?
83
+ end
84
+ end
85
+
86
+ describe BinData::Struct, "with onlyif fields" do
87
+ let(:obj) {
88
+ params = { fields: [
89
+ [:int8, :a, {initial_value: 2}],
90
+ [:int8, :b, {onlyif: -> { a.odd? }}]
91
+ ] }
92
+ BinData::Struct.new(params)
93
+ }
94
+
95
+ it "#fieldnames includes all fields" do
96
+ _(obj.field_names).must_equal [:a, :b]
97
+ end
98
+
99
+ it "#snapshot checks for onlyif" do
100
+ _(obj.snapshot.keys).must_equal [:a]
101
+ end
102
+
103
+ it "includes fields when required" do
104
+ refute obj.b?
105
+ obj.a = 3
106
+ assert obj.b?
66
107
  end
67
108
  end
68
109
 
@@ -140,10 +181,16 @@ describe BinData::Struct, "with multiple fields" do
140
181
  _(obj[:a]).must_equal 1
141
182
  end
142
183
 
143
- it "handles not existing elements" do
184
+ it "handles nonexistent elements" do
144
185
  _(obj[:does_not_exist]).must_be_nil
145
186
  end
146
187
 
188
+ it "ignores setting nonexistent elements" do
189
+ snap = obj.snapshot
190
+ obj[:does_not_exist] = 3
191
+ _(obj.snapshot).must_equal snap
192
+ end
193
+
147
194
  it "writes elements dynamically" do
148
195
  obj[:a] = 2
149
196
  _(obj.a).must_equal 2
@@ -225,6 +272,20 @@ describe BinData::Struct, "with multiple fields" do
225
272
  obj.snapshot.each_pair { |k, v| keys << k }
226
273
  _(keys).must_equal [:a, :b]
227
274
  end
275
+
276
+ it "accesses field" do
277
+ _(obj.snapshot[:a]).must_equal 1
278
+ end
279
+
280
+ it "fails on unknown method call" do
281
+ _ { obj.snapshot.does_not_exist }.must_raise NoMethodError
282
+ end
283
+
284
+ it "will not set attribute with nil value" do
285
+ refute obj.snapshot.key?(:foo)
286
+ obj.snapshot[:foo] = nil
287
+ refute obj.snapshot.key?(:foo)
288
+ end
228
289
  end
229
290
  end
230
291
 
@@ -402,30 +463,44 @@ describe BinData::Struct, "with byte_align" do
402
463
  let(:obj) {
403
464
  params = { fields: [[:int8, :a],
404
465
  [:int8, :b, byte_align: 5],
405
- [:bit2, :c],
466
+ [:bit2, :c, onlyif: -> { a == 1}],
406
467
  [:int8, :d, byte_align: 3]] }
407
468
  BinData::Struct.new(params)
408
469
  }
409
470
 
410
471
  it "has #num_bytes" do
472
+ _(obj.num_bytes).must_equal 7
473
+ end
474
+
475
+ it "has #num_bytes with onlyif" do
476
+ obj.a = 1
411
477
  _(obj.num_bytes).must_equal 10
412
478
  end
413
479
 
414
- it "reads" do
480
+ it "reads with onlyif" do
415
481
  obj.read("\x01\x00\x00\x00\x00\x02\xc0\x00\x00\x04")
416
482
  _(obj.snapshot).must_equal({ a: 1, b: 2, c: 3, d: 4 })
417
483
  end
418
484
 
419
- it "writes" do
485
+ it "reads without onlyif" do
486
+ obj.read("\x00\x00\x00\x00\x00\x02\x04")
487
+ _(obj.snapshot).must_equal({ a: 0, b: 2, d: 4 })
488
+ end
489
+
490
+ it "writes with onlyif" do
420
491
  obj.assign(a: 1, b: 2, c: 3, d: 4)
421
492
  _(obj.to_binary_s).must_equal_binary "\x01\x00\x00\x00\x00\x02\xc0\x00\x00\x04"
422
493
  end
423
494
 
495
+ it "writes without onlyif" do
496
+ obj.assign(a: 0, b: 2, c: 3, d: 4)
497
+ _(obj.to_binary_s).must_equal_binary "\x00\x00\x00\x00\x00\x02\x04"
498
+ end
499
+
424
500
  it "has correct offsets" do
425
501
  _(obj.a.rel_offset).must_equal 0
426
502
  _(obj.b.rel_offset).must_equal 5
427
- _(obj.c.rel_offset).must_equal 6
428
- _(obj.d.rel_offset).must_equal 9
503
+ _(obj.d.rel_offset).must_equal 6
429
504
  end
430
505
  end
431
506
 
data/test/system_test.rb CHANGED
@@ -229,6 +229,19 @@ describe "Tracing" do
229
229
 
230
230
  _(io.value).must_equal "obj => \"000000000011111111112222222222...\n"
231
231
  end
232
+
233
+ it "can be nested" do
234
+ obj = BinData::String.new(read_length: 5)
235
+
236
+ io = StringIO.new
237
+ BinData::trace_reading(io) {
238
+ BinData::trace_reading(io) {
239
+ obj.read("12345")
240
+ }
241
+ }
242
+
243
+ _(io.value).must_equal "obj => \"12345\"\n"
244
+ end
232
245
  end
233
246
 
234
247
  describe "Forward referencing with Primitive" do
@@ -381,7 +394,7 @@ describe BinData::Record, "encoding" do
381
394
  end
382
395
 
383
396
  it "returns binary encoded data despite Encoding.default_internal" do
384
- w, $-w = $-w, false
397
+ w, $-w = $-w, nil
385
398
  before_enc = Encoding.default_internal
386
399
 
387
400
  begin
@@ -394,3 +407,108 @@ describe BinData::Record, "encoding" do
394
407
  end
395
408
  end
396
409
  end
410
+
411
+ describe BinData::Record, "buffer num_bytes" do
412
+ class BufferNumBytesRecord < BinData::Record
413
+ buffer :b, length: 10 do
414
+ int8 :a
415
+ count_bytes_remaining :nbytes
416
+ end
417
+ end
418
+
419
+ it "counts bytes remaining in the buffer" do
420
+ obj = BufferNumBytesRecord.read "12345678901234567890"
421
+ _(obj.b.nbytes).must_equal 9
422
+ end
423
+
424
+ it "counts bytes remaining in the buffer with short streams" do
425
+ obj = BufferNumBytesRecord.read "12345"
426
+ _(obj.b.nbytes).must_equal 4
427
+ end
428
+
429
+ it "assumes buffer is full with non-seekable short streams" do
430
+ rd, wr = IO::pipe
431
+ io = BinData::IO::Read.new(rd)
432
+ wr.write "12345"
433
+ wr.close
434
+
435
+ obj = BufferNumBytesRecord.read(io)
436
+ _(obj.b.nbytes).must_equal 9
437
+ rd.close
438
+ end
439
+ end
440
+
441
+ describe BinData::Buffer, "with seek_abs" do
442
+ class BufferSkipRecord < BinData::Record
443
+ endian :little
444
+ mandatory_parameter :seek_offset
445
+
446
+ uint8
447
+ buffer :buf, length: 5 do
448
+ uint8
449
+ uint8
450
+ skip to_abs_offset: :seek_offset
451
+ uint8 :a
452
+ end
453
+ uint8
454
+ end
455
+
456
+ let(:str) { "\001\002\003\004\005\006\007" }
457
+
458
+ ## TODO: enable this if we decide to allow backwards seeking
459
+ #backwards_seeking = false
460
+ #
461
+ #it "won't seek backwards before buffer" do
462
+ # skip unless backwards_seeking
463
+ # _ { BufferSkipRecord.new(seek_offset: 0).read(str) }.must_raise(IOError)
464
+ #end
465
+ #
466
+ #it "seeks backwards to start of buffer" do
467
+ # skip unless backwards_seeking
468
+ # obj = BufferSkipRecord.new(seek_offset: 1).read(str)
469
+ # _(obj.buf.a).must_equal 2
470
+ #end
471
+ #
472
+ #it "seeks backwards inside buffer" do
473
+ # skip unless backwards_seeking
474
+ # obj = BufferSkipRecord.new(seek_offset: 2).read(str)
475
+ # _(obj.buf.a).must_equal 3
476
+ #end
477
+
478
+ it "seeks forwards inside buffer" do
479
+ obj = BufferSkipRecord.new(seek_offset: 4).read(str)
480
+ _(obj.buf.a).must_equal 5
481
+ end
482
+
483
+ it "seeks to end of buffer" do
484
+ obj = BufferSkipRecord.new(seek_offset: 5).read(str)
485
+ _(obj.buf.a).must_equal 6
486
+ end
487
+
488
+ it "won't seek after buffer" do
489
+ _ { BufferSkipRecord.new(seek_offset: 6).read(str) }.must_raise(IOError)
490
+ end
491
+ end
492
+
493
+
494
+ describe BinData::Record, "buffered readahead" do
495
+ class BufferedReadaheadRecord < BinData::Record
496
+ buffer :a, length: 5 do
497
+ skip do
498
+ string read_length: 1, assert: "X"
499
+ end
500
+ string :b, read_length: 1
501
+ end
502
+ string :c, read_length: 1
503
+ end
504
+
505
+ it "reads ahead inside the buffer" do
506
+ obj = BufferedReadaheadRecord.read "12X4567890"
507
+ _(obj.a.b).must_equal "X"
508
+ _(obj.c).must_equal "6"
509
+ end
510
+
511
+ it "doesn't readahead outside the buffer" do
512
+ _ { BufferedReadaheadRecord.read "123456X890" }.must_raise IOError
513
+ end
514
+ end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'rubygems'
2
2
 
3
- require 'coveralls'
4
- Coveralls.wear!
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ enable_coverage :branch
6
+ end
5
7
 
6
8
  require 'minitest/autorun'
7
9
  require 'stringio'
@@ -30,32 +32,45 @@ module Kernel
30
32
  def value_read_from_written
31
33
  self.class.read(self.to_binary_s)
32
34
  end
35
+ end
33
36
 
34
- def must_equal_binary(expected)
35
- must_equal expected.dup.force_encoding(Encoding::BINARY)
37
+ module Minitest::Assertions
38
+ def assert_equals_binary(expected, actual)
39
+ assert_equal expected.dup.force_encoding(Encoding::BINARY), actual
36
40
  end
37
41
 
38
- def must_raise_on_line(exp, line, msg = nil)
39
- ex = self.must_raise exp
40
- (ex.message).must_equal msg if msg
42
+ def assert_raises_on_line(exp, line, msg = nil, &block)
43
+ ex = assert_raises(exp, &block)
44
+ assert_equal(msg, ex.message) if msg
45
+
46
+ line_num_regex = /(.*):(\d+)(:in.*)$/
47
+
48
+ filename = line_num_regex.match(ex.backtrace[0])[1]
41
49
 
42
- idx = ex.backtrace.find_index { |bt| /:in `must_raise_on_line'$/ =~ bt }
50
+ filtered = ex.backtrace.grep(/^#{Regexp.escape(filename)}/)
51
+ top = filtered.grep(Regexp.new(Regexp.escape("in <top (required)>")))
43
52
 
44
- line_num_regex = /.*:(\d+)(:.*|$)/
45
- err_line = line_num_regex.match(ex.backtrace[0])[1].to_i
46
- ref_line = line_num_regex.match(ex.backtrace[idx + 1])[1].to_i
53
+ err_line = line_num_regex.match(filtered[0])[2].to_i
54
+ ref_line = line_num_regex.match(top[0])[2].to_i - 1
47
55
 
48
- (err_line - ref_line).must_equal line
56
+ assert_equal((err_line - ref_line), line)
49
57
  end
50
58
 
51
- def must_warn(msg, &block)
59
+ def assert_warns(msg, &block)
52
60
  result = ""
53
61
  callable = proc { |str|
54
62
  result = str
55
63
  }
56
- self.stub(:warn, callable) do
64
+ Kernel.stub(:warn, callable) do
57
65
  block.call
58
66
  end
59
- (result).must_equal msg
67
+
68
+ assert_equal msg, result
60
69
  end
61
70
  end
71
+
72
+ module Minitest::Expectations
73
+ infect_an_assertion :assert_equals_binary, :must_equal_binary
74
+ infect_an_assertion :assert_raises_on_line, :must_raise_on_line, :block
75
+ infect_an_assertion :assert_warns, :must_warn, :block
76
+ end
@@ -15,6 +15,18 @@ describe BinData::Base, "when defining" do
15
15
  }.must_raise RuntimeError
16
16
  end
17
17
 
18
+ it "fails if #initialize is overridden on BasePrimitive" do
19
+ class BasePrimitiveWithInitialize < BinData::String
20
+ def initialize(params = {}, parent = nil)
21
+ super
22
+ end
23
+ end
24
+
25
+ _ {
26
+ BasePrimitiveWithInitialize.new
27
+ }.must_raise RuntimeError
28
+ end
29
+
18
30
  it "handles if #initialize is naively renamed to #initialize_instance" do
19
31
  class BaseWithInitializeInstance < BinData::Base
20
32
  def initialize_instance(params = {}, parent = nil)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bindata
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.15
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dion Mendel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-07 00:00:00.000000000 Z
11
+ date: 1980-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -31,9 +31,6 @@ dependencies:
31
31
  - - ">"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 5.0.0
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: 5.12.0
37
34
  type: :development
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
@@ -41,11 +38,8 @@ dependencies:
41
38
  - - ">"
42
39
  - !ruby/object:Gem::Version
43
40
  version: 5.0.0
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: 5.12.0
47
41
  - !ruby/object:Gem::Dependency
48
- name: coveralls
42
+ name: simplecov
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
45
  - - ">="
@@ -65,7 +59,7 @@ description: |
65
59
  data is, and BinData works out *how* to read and write data in this
66
60
  format. It is an easier ( and more readable ) alternative to
67
61
  ruby's #pack and #unpack methods.
68
- email: bindata@dm9.info
62
+ email: bindata@dmau.org
69
63
  executables: []
70
64
  extensions: []
71
65
  extra_rdoc_files:
@@ -101,18 +95,25 @@ files:
101
95
  - lib/bindata/io.rb
102
96
  - lib/bindata/lazy.rb
103
97
  - lib/bindata/name.rb
104
- - lib/bindata/offset.rb
105
98
  - lib/bindata/params.rb
106
99
  - lib/bindata/primitive.rb
107
100
  - lib/bindata/record.rb
108
101
  - lib/bindata/registry.rb
109
102
  - lib/bindata/rest.rb
110
103
  - lib/bindata/sanitize.rb
104
+ - lib/bindata/section.rb
111
105
  - lib/bindata/skip.rb
112
106
  - lib/bindata/string.rb
113
107
  - lib/bindata/stringz.rb
114
108
  - lib/bindata/struct.rb
115
109
  - lib/bindata/trace.rb
110
+ - lib/bindata/transform/brotli.rb
111
+ - lib/bindata/transform/lz4.rb
112
+ - lib/bindata/transform/lzma.rb
113
+ - lib/bindata/transform/xor.rb
114
+ - lib/bindata/transform/xz.rb
115
+ - lib/bindata/transform/zlib.rb
116
+ - lib/bindata/transform/zstd.rb
116
117
  - lib/bindata/uint8_array.rb
117
118
  - lib/bindata/version.rb
118
119
  - lib/bindata/virtual.rb
@@ -130,12 +131,12 @@ files:
130
131
  - test/int_test.rb
131
132
  - test/io_test.rb
132
133
  - test/lazy_test.rb
133
- - test/offset_test.rb
134
134
  - test/params_test.rb
135
135
  - test/primitive_test.rb
136
136
  - test/record_test.rb
137
137
  - test/registry_test.rb
138
138
  - test/rest_test.rb
139
+ - test/section_test.rb
139
140
  - test/skip_test.rb
140
141
  - test/string_test.rb
141
142
  - test/stringz_test.rb
@@ -148,8 +149,9 @@ files:
148
149
  homepage: https://github.com/dmendel/bindata
149
150
  licenses:
150
151
  - BSD-2-Clause
151
- metadata: {}
152
- post_install_message:
152
+ metadata:
153
+ changelog_uri: https://github.com/dmendel/bindata/blob/master/ChangeLog.rdoc
154
+ post_install_message:
153
155
  rdoc_options:
154
156
  - "--main"
155
157
  - NEWS.rdoc
@@ -159,15 +161,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
161
  requirements:
160
162
  - - ">="
161
163
  - !ruby/object:Gem::Version
162
- version: 2.4.0
164
+ version: 2.5.0
163
165
  required_rubygems_version: !ruby/object:Gem::Requirement
164
166
  requirements:
165
167
  - - ">="
166
168
  - !ruby/object:Gem::Version
167
169
  version: '0'
168
170
  requirements: []
169
- rubygems_version: 3.3.7
170
- signing_key:
171
+ rubygems_version: 3.3.27
172
+ signing_key:
171
173
  specification_version: 4
172
174
  summary: A declarative way to read and write binary file formats
173
175
  test_files: []
@@ -1,94 +0,0 @@
1
- module BinData
2
- # WARNING: THIS IS UNSUPPORTED!!
3
- #
4
- # This was a (failed) experimental feature that allowed seeking within the
5
- # input stream. It remains here for backwards compatability for the few
6
- # people that used it.
7
- #
8
- # The official way to skip around the stream is to use BinData::Skip with
9
- # the `:to_abs_offset` parameter.
10
- #
11
- # == Parameters
12
- #
13
- # Parameters may be provided at initialisation to control the behaviour of
14
- # an object. These parameters are:
15
- #
16
- # [<tt>:check_offset</tt>] Raise an error if the current IO offset doesn't
17
- # meet this criteria. A boolean return indicates
18
- # success or failure. Any other return is compared
19
- # to the current offset. The variable +offset+
20
- # is made available to any lambda assigned to
21
- # this parameter. This parameter is only checked
22
- # before reading.
23
- # [<tt>:adjust_offset</tt>] Ensures that the current IO offset is at this
24
- # position before reading. This is like
25
- # <tt>:check_offset</tt>, except that it will
26
- # adjust the IO offset instead of raising an error.
27
- module CheckOrAdjustOffsetPlugin
28
-
29
- def self.included(base) #:nodoc:
30
- base.optional_parameters :check_offset, :adjust_offset
31
- base.mutually_exclusive_parameters :check_offset, :adjust_offset
32
- end
33
-
34
- def initialize_shared_instance
35
- extend CheckOffsetMixin if has_parameter?(:check_offset)
36
- extend AdjustOffsetMixin if has_parameter?(:adjust_offset)
37
- super
38
- end
39
-
40
- module CheckOffsetMixin
41
- def do_read(io) #:nodoc:
42
- check_offset(io)
43
- super(io)
44
- end
45
-
46
- #---------------
47
- private
48
-
49
- def check_offset(io)
50
- actual_offset = io.offset
51
- expected = eval_parameter(:check_offset, offset: actual_offset)
52
-
53
- if !expected
54
- raise ValidityError, "offset not as expected for #{debug_name}"
55
- elsif actual_offset != expected && expected != true
56
- raise ValidityError,
57
- "offset is '#{actual_offset}' but " +
58
- "expected '#{expected}' for #{debug_name}"
59
- end
60
- end
61
- end
62
-
63
- module AdjustOffsetMixin
64
- def do_read(io) #:nodoc:
65
- adjust_offset(io)
66
- super(io)
67
- end
68
-
69
- #---------------
70
- private
71
-
72
- def adjust_offset(io)
73
- actual_offset = io.offset
74
- expected = eval_parameter(:adjust_offset)
75
- if actual_offset != expected
76
- begin
77
- seek = expected - actual_offset
78
- io.seekbytes(seek)
79
- warn "adjusting stream position by #{seek} bytes" if $VERBOSE
80
- rescue
81
- raise ValidityError,
82
- "offset is '#{actual_offset}' but couldn't seek to " +
83
- "expected '#{expected}' for #{debug_name}"
84
- end
85
- end
86
- end
87
- end
88
- end
89
-
90
- # Add these offset options to Base
91
- class Base
92
- include CheckOrAdjustOffsetPlugin
93
- end
94
- end