bindata 2.4.10 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.rdoc +39 -0
  3. data/LICENSE +25 -0
  4. data/NEWS.rdoc +5 -0
  5. data/README.md +6 -9
  6. data/bindata.gemspec +9 -4
  7. data/examples/NBT.txt +1 -1
  8. data/examples/list.rb +1 -1
  9. data/lib/bindata/alignment.rb +15 -7
  10. data/lib/bindata/array.rb +54 -54
  11. data/lib/bindata/base.rb +14 -25
  12. data/lib/bindata/base_primitive.rb +24 -20
  13. data/lib/bindata/bits.rb +15 -15
  14. data/lib/bindata/buffer.rb +89 -11
  15. data/lib/bindata/choice.rb +9 -6
  16. data/lib/bindata/count_bytes_remaining.rb +1 -1
  17. data/lib/bindata/delayed_io.rb +18 -10
  18. data/lib/bindata/dsl.rb +37 -35
  19. data/lib/bindata/float.rb +3 -3
  20. data/lib/bindata/framework.rb +8 -10
  21. data/lib/bindata/int.rb +14 -16
  22. data/lib/bindata/io.rb +276 -253
  23. data/lib/bindata/name.rb +1 -1
  24. data/lib/bindata/params.rb +9 -7
  25. data/lib/bindata/primitive.rb +3 -3
  26. data/lib/bindata/registry.rb +18 -18
  27. data/lib/bindata/rest.rb +1 -1
  28. data/lib/bindata/sanitize.rb +9 -16
  29. data/lib/bindata/section.rb +97 -0
  30. data/lib/bindata/skip.rb +140 -51
  31. data/lib/bindata/string.rb +9 -9
  32. data/lib/bindata/stringz.rb +12 -10
  33. data/lib/bindata/struct.rb +92 -68
  34. data/lib/bindata/trace.rb +35 -42
  35. data/lib/bindata/transform/brotli.rb +35 -0
  36. data/lib/bindata/transform/lz4.rb +35 -0
  37. data/lib/bindata/transform/lzma.rb +35 -0
  38. data/lib/bindata/transform/xor.rb +19 -0
  39. data/lib/bindata/transform/xz.rb +35 -0
  40. data/lib/bindata/transform/zlib.rb +33 -0
  41. data/lib/bindata/transform/zstd.rb +35 -0
  42. data/lib/bindata/uint8_array.rb +2 -2
  43. data/lib/bindata/version.rb +1 -1
  44. data/lib/bindata/virtual.rb +4 -7
  45. data/lib/bindata/warnings.rb +1 -1
  46. data/lib/bindata.rb +1 -0
  47. data/test/alignment_test.rb +8 -8
  48. data/test/array_test.rb +98 -96
  49. data/test/base_primitive_test.rb +47 -47
  50. data/test/base_test.rb +24 -24
  51. data/test/bits_test.rb +15 -15
  52. data/test/buffer_test.rb +31 -22
  53. data/test/choice_test.rb +32 -32
  54. data/test/count_bytes_remaining_test.rb +8 -8
  55. data/test/delayed_io_test.rb +91 -30
  56. data/test/float_test.rb +8 -8
  57. data/test/int_test.rb +14 -14
  58. data/test/io_test.rb +110 -302
  59. data/test/lazy_test.rb +38 -38
  60. data/test/params_test.rb +19 -19
  61. data/test/primitive_test.rb +26 -26
  62. data/test/record_test.rb +99 -99
  63. data/test/registry_test.rb +43 -43
  64. data/test/rest_test.rb +5 -5
  65. data/test/section_test.rb +111 -0
  66. data/test/skip_test.rb +71 -26
  67. data/test/string_test.rb +60 -60
  68. data/test/stringz_test.rb +34 -26
  69. data/test/struct_test.rb +167 -92
  70. data/test/system_test.rb +159 -41
  71. data/test/test_helper.rb +24 -13
  72. data/test/uint8_array_test.rb +6 -6
  73. data/test/virtual_test.rb +7 -7
  74. data/test/warnings_test.rb +14 -2
  75. metadata +19 -22
  76. data/.gitignore +0 -2
  77. data/.travis.yml +0 -15
  78. data/BSDL +0 -22
  79. data/COPYING +0 -52
  80. data/INSTALL +0 -12
  81. data/lib/bindata/offset.rb +0 -94
  82. data/test/offset_test.rb +0 -100
data/test/buffer_test.rb CHANGED
@@ -6,26 +6,26 @@ describe BinData::Buffer, "when instantiating" do
6
6
  describe "with no mandatory parameters supplied" do
7
7
  it "raises an error" do
8
8
  args = {}
9
- lambda { BinData::Buffer.new(args) }.must_raise ArgumentError
9
+ _ { BinData::Buffer.new(args) }.must_raise ArgumentError
10
10
  end
11
11
  end
12
12
 
13
13
  describe "with some but not all mandatory parameters supplied" do
14
14
  it "raises an error" do
15
15
  args = {length: 3}
16
- lambda { BinData::Buffer.new(args) }.must_raise ArgumentError
16
+ _ { BinData::Buffer.new(args) }.must_raise ArgumentError
17
17
  end
18
18
  end
19
19
 
20
20
  it "fails if a given type is unknown" do
21
21
  args = {type: :does_not_exist, length: 3}
22
- lambda { BinData::Buffer.new(args) }.must_raise BinData::UnRegisteredTypeError
22
+ _ { BinData::Buffer.new(args) }.must_raise BinData::UnRegisteredTypeError
23
23
  end
24
24
 
25
25
  it "accepts BinData::Base as :type" do
26
26
  obj = BinData::Int8.new(initial_value: 5)
27
27
  array = BinData::Buffer.new(type: obj, length: 3)
28
- array.must_equal 5
28
+ _(array).must_equal 5
29
29
  end
30
30
  end
31
31
 
@@ -39,29 +39,29 @@ describe BinData::Buffer, "subclassed with a single type" do
39
39
 
40
40
  it "behaves as type" do
41
41
  obj = IntBuffer.new(3)
42
- obj.must_equal 3
42
+ _(obj).must_equal 3
43
43
  end
44
44
 
45
45
  it "reads data" do
46
46
  obj = IntBuffer.read "\001\002\003\004\005"
47
- obj.must_equal 0x0102
47
+ _(obj).must_equal 0x0102
48
48
  end
49
49
 
50
50
  it "writes data" do
51
51
  obj = IntBuffer.new(3)
52
- obj.to_binary_s.must_equal_binary "\000\003\000\000\000"
52
+ _(obj.to_binary_s).must_equal_binary "\000\003\000\000\000"
53
53
  end
54
54
 
55
55
  it "has total num_bytes" do
56
56
  obj = IntBuffer.new
57
57
  assert obj.clear?
58
- obj.num_bytes.must_equal 5
58
+ _(obj.num_bytes).must_equal 5
59
59
  end
60
60
 
61
61
  it "has raw_num_bytes" do
62
62
  obj = IntBuffer.new
63
63
  assert obj.clear?
64
- obj.raw_num_bytes.must_equal 2
64
+ _(obj.raw_num_bytes).must_equal 2
65
65
  end
66
66
  end
67
67
 
@@ -76,29 +76,29 @@ describe BinData::Buffer, "subclassed with multiple types" do
76
76
 
77
77
  it "behaves as type" do
78
78
  obj = TupleBuffer.new(a: 1, b: 2)
79
- obj.a.must_equal 1
80
- obj.b.must_equal 2
79
+ _(obj.a).must_equal 1
80
+ _(obj.b).must_equal 2
81
81
  end
82
82
 
83
83
  it "has total num_bytes" do
84
84
  obj = TupleBuffer.new
85
- obj.num_bytes.must_equal 5
85
+ _(obj.num_bytes).must_equal 5
86
86
  end
87
87
 
88
88
  it "has raw_num_bytes" do
89
89
  obj = TupleBuffer.new
90
- obj.raw_num_bytes.must_equal 4
90
+ _(obj.raw_num_bytes).must_equal 4
91
91
  end
92
92
 
93
93
  it "reads data" do
94
94
  obj = TupleBuffer.read "\001\002\003\004\005"
95
- obj.a.must_equal 0x0102
96
- obj.b.must_equal 0x0304
95
+ _(obj.a).must_equal 0x0102
96
+ _(obj.b).must_equal 0x0304
97
97
  end
98
98
 
99
99
  it "writes data" do
100
100
  obj = TupleBuffer.new(a: 1, b: 2)
101
- obj.to_binary_s.must_equal_binary "\000\001\000\002\000"
101
+ _(obj.to_binary_s).must_equal_binary "\000\001\000\002\000"
102
102
  end
103
103
  end
104
104
 
@@ -115,12 +115,12 @@ describe BinData::Buffer, "inside a Record" do
115
115
 
116
116
  it "reads" do
117
117
  obj = BufferRecord.read "\007\000\004\000\005\000\006\000\000ZZ"
118
- obj.list.must_equal [4, 5, 6]
118
+ _(obj.list).must_equal [4, 5, 6]
119
119
  end
120
120
 
121
121
  it "writes" do
122
122
  obj = BufferRecord.new(list: [1, 2, 3, 4, 5])
123
- obj.to_binary_s.must_equal_binary "\013\000\001\000\002\000\003\000\004\000\005\000\000ZZ"
123
+ _(obj.to_binary_s).must_equal_binary "\013\000\001\000\002\000\003\000\004\000\005\000\000ZZ"
124
124
  end
125
125
  end
126
126
 
@@ -139,9 +139,18 @@ describe BinData::Buffer, "nested buffers" do
139
139
 
140
140
  it "restricts large nested buffer" do
141
141
  obj = NestedBufferRecord.read "abcdefghijklmnopqrst"
142
- obj.a.aa.must_equal "abcde"
143
- obj.a.bb.must_equal "fghij"
144
- obj.b.must_equal "klmno"
142
+ _(obj.a.aa).must_equal "abcde"
143
+ _(obj.a.bb).must_equal "fghij"
144
+ _(obj.b).must_equal "klmno"
145
+ end
146
+
147
+ it "pads undersize writes" do
148
+ obj = NestedBufferRecord.new
149
+ obj.a.aa = "abc"
150
+ obj.a.bb = "ABC"
151
+ obj.b = "123"
152
+
153
+ _(obj.to_binary_s).must_equal_binary "abc\000\000ABC\000\000123"
145
154
  end
146
155
 
147
156
  it "restricts oversize writes" do
@@ -150,6 +159,6 @@ describe BinData::Buffer, "nested buffers" do
150
159
  obj.a.bb = "ABCDEFGHIJ"
151
160
  obj.b = "12345"
152
161
 
153
- obj.to_binary_s.must_equal_binary "abcdeABCDE12345"
162
+ _(obj.to_binary_s).must_equal_binary "abcdeABCDE12345"
154
163
  end
155
164
  end
data/test/choice_test.rb CHANGED
@@ -26,84 +26,84 @@ end
26
26
  describe BinData::Choice, "when instantiating" do
27
27
  it "ensures mandatory parameters are supplied" do
28
28
  args = {}
29
- lambda { BinData::Choice.new(args) }.must_raise ArgumentError
29
+ _ { BinData::Choice.new(args) }.must_raise ArgumentError
30
30
 
31
31
  args = {selection: 1}
32
- lambda { BinData::Choice.new(args) }.must_raise ArgumentError
32
+ _ { BinData::Choice.new(args) }.must_raise ArgumentError
33
33
 
34
34
  args = {choices: []}
35
- lambda { BinData::Choice.new(args) }.must_raise ArgumentError
35
+ _ { BinData::Choice.new(args) }.must_raise ArgumentError
36
36
  end
37
37
 
38
38
  it "fails when a given type is unknown" do
39
39
  args = {choices: [:does_not_exist], selection: 0}
40
- lambda { BinData::Choice.new(args) }.must_raise BinData::UnRegisteredTypeError
40
+ _ { BinData::Choice.new(args) }.must_raise BinData::UnRegisteredTypeError
41
41
  end
42
42
 
43
43
  it "fails when a given type is unknown" do
44
44
  args = {choices: {0 => :does_not_exist}, selection: 0}
45
- lambda { BinData::Choice.new(args) }.must_raise BinData::UnRegisteredTypeError
45
+ _ { BinData::Choice.new(args) }.must_raise BinData::UnRegisteredTypeError
46
46
  end
47
47
 
48
48
  it "fails when :choices Hash has a symbol as key" do
49
49
  args = {choices: {a: :uint8}, selection: 0}
50
- lambda { BinData::Choice.new(args) }.must_raise ArgumentError
50
+ _ { BinData::Choice.new(args) }.must_raise ArgumentError
51
51
  end
52
52
 
53
53
  it "fails when :choices Hash has a nil key" do
54
54
  args = {choices: {nil => :uint8}, selection: 0}
55
- lambda { BinData::Choice.new(args) }.must_raise ArgumentError
55
+ _ { BinData::Choice.new(args) }.must_raise ArgumentError
56
56
  end
57
57
  end
58
58
 
59
59
  module ChoiceInitializedWithArrayOrHash
60
60
  def test_can_select_the_choice
61
61
  obj.choice = 3
62
- obj.must_equal 30
62
+ _(obj).must_equal 30
63
63
  end
64
64
 
65
65
  def test_shows_the_current_selection
66
66
  obj.choice = 3
67
- obj.selection.must_equal 3
67
+ _(obj.selection).must_equal 3
68
68
  end
69
69
 
70
70
  def test_forwards_snapshot
71
71
  obj.choice = 3
72
- obj.snapshot.must_equal 30
72
+ _(obj.snapshot).must_equal 30
73
73
  end
74
74
 
75
75
  def test_can_change_the_choice
76
76
  obj.choice = 3
77
77
 
78
78
  obj.choice = 7
79
- obj.must_equal 70
79
+ _(obj).must_equal 70
80
80
  end
81
81
 
82
82
  def test_fails_if_no_choice_has_been_set
83
- lambda { obj.to_s }.must_raise IndexError
83
+ _ { obj.to_s }.must_raise IndexError
84
84
  end
85
85
 
86
86
  def test_wont_select_an_invalid_choice
87
87
  obj.choice = 99
88
- lambda { obj.to_s }.must_raise IndexError
88
+ _ { obj.to_s }.must_raise IndexError
89
89
  end
90
90
 
91
91
  def test_wont_select_a_nil_choice
92
92
  obj.choice = 1
93
- lambda { obj.to_s }.must_raise IndexError
93
+ _ { obj.to_s }.must_raise IndexError
94
94
  end
95
95
 
96
96
  def test_handles_missing_methods_correctly
97
97
  obj.choice = 3
98
98
 
99
- obj.must_respond_to :value
100
- obj.wont_respond_to :does_not_exist
101
- lambda { obj.does_not_exist }.must_raise NoMethodError
99
+ _(obj).must_respond_to :value
100
+ _(obj).wont_respond_to :does_not_exist
101
+ _ { obj.does_not_exist }.must_raise NoMethodError
102
102
  end
103
103
 
104
104
  def test_delegates_methods_to_the_selected_single_choice
105
105
  obj.choice = 5
106
- obj.num_bytes.must_equal 1
106
+ _(obj.num_bytes).must_equal 1
107
107
  end
108
108
  end
109
109
 
@@ -138,7 +138,7 @@ describe BinData::Choice, "with single values" do
138
138
  it "assigns raw values" do
139
139
  obj.choice = 3
140
140
  obj.assign(254)
141
- obj.must_equal 254
141
+ _(obj).must_equal 254
142
142
  end
143
143
 
144
144
  it "assigns BinData values" do
@@ -146,7 +146,7 @@ describe BinData::Choice, "with single values" do
146
146
 
147
147
  obj.choice = 3
148
148
  obj.assign(data)
149
- obj.must_equal 11
149
+ _(obj).must_equal 11
150
150
  end
151
151
 
152
152
  it "clears" do
@@ -154,7 +154,7 @@ describe BinData::Choice, "with single values" do
154
154
  obj.assign(254)
155
155
 
156
156
  obj.clear
157
- obj.must_equal 0
157
+ _(obj).must_equal 0
158
158
  end
159
159
 
160
160
  it "clears all possible choices" do
@@ -166,7 +166,7 @@ describe BinData::Choice, "with single values" do
166
166
  obj.clear
167
167
 
168
168
  obj.choice = 3
169
- obj.must_equal 0
169
+ _(obj).must_equal 0
170
170
  end
171
171
 
172
172
  it "is clear on initialisation" do
@@ -187,15 +187,15 @@ describe BinData::Choice, "with single values" do
187
187
  obj.assign(254)
188
188
 
189
189
  obj.choice = 7
190
- obj.wont_equal 254
190
+ _(obj).wont_equal 254
191
191
  end
192
192
 
193
193
  it "behaves as value" do
194
194
  obj.choice = 3
195
195
  obj.assign(5)
196
196
 
197
- (obj + 1).must_equal 6
198
- (1 + obj).must_equal 6
197
+ _((obj + 1)).must_equal 6
198
+ _((1 + obj)).must_equal 6
199
199
  end
200
200
  end
201
201
 
@@ -210,7 +210,7 @@ describe BinData::Choice, "with copy_on_change => true" do
210
210
  obj.assign(254)
211
211
 
212
212
  obj.choice = 7
213
- obj.must_equal 254
213
+ _(obj).must_equal 254
214
214
  end
215
215
  end
216
216
 
@@ -219,12 +219,12 @@ describe BinData::Choice, "with :default" do
219
219
 
220
220
  it "selects for existing case" do
221
221
  obj = BinData::Choice.new(selection: "a", choices: choices)
222
- obj.num_bytes.must_equal 1
222
+ _(obj.num_bytes).must_equal 1
223
223
  end
224
224
 
225
225
  it "selects for default case" do
226
226
  obj = BinData::Choice.new(selection: "other", choices: choices)
227
- obj.num_bytes.must_equal 2
227
+ _(obj.num_bytes).must_equal 2
228
228
  end
229
229
  end
230
230
 
@@ -240,16 +240,16 @@ describe BinData::Choice, "subclassed with default parameters" do
240
240
 
241
241
  it "sets initial selection" do
242
242
  obj = DerivedChoice.new
243
- obj.num_bytes.must_equal 2
243
+ _(obj.num_bytes).must_equal 2
244
244
  end
245
245
 
246
- it "overides default parameter" do
246
+ it "overrides default parameter" do
247
247
  obj = DerivedChoice.new(selection: 'b')
248
- obj.num_bytes.must_equal 4
248
+ _(obj.num_bytes).must_equal 4
249
249
  end
250
250
 
251
251
  it "selects default selection" do
252
252
  obj = DerivedChoice.new(selection: 'z')
253
- obj.num_bytes.must_equal 8
253
+ _(obj.num_bytes).must_equal 8
254
254
  end
255
255
  end
@@ -6,35 +6,35 @@ describe BinData::CountBytesRemaining do
6
6
  let(:obj) { BinData::CountBytesRemaining.new }
7
7
 
8
8
  it "initial state" do
9
- obj.must_equal 0
10
- obj.num_bytes.must_equal 0
9
+ _(obj).must_equal 0
10
+ _(obj.num_bytes).must_equal 0
11
11
  end
12
12
 
13
13
  it "counts till end of stream" do
14
14
  data = "abcdefghij"
15
- obj.read(data).must_equal 10
15
+ _(obj.read(data)).must_equal 10
16
16
  end
17
17
 
18
18
  it "does not read any data" do
19
19
  io = StringIO.new "abcdefghij"
20
20
  obj.read(io)
21
21
 
22
- io.pos.must_equal 0
22
+ _(io.pos).must_equal 0
23
23
  end
24
24
 
25
25
  it "does not write any data" do
26
- obj.to_binary_s.must_equal_binary ""
26
+ _(obj.to_binary_s).must_equal_binary ""
27
27
  end
28
28
 
29
29
  it "allows setting value for completeness" do
30
30
  obj.assign("123")
31
- obj.must_equal "123"
32
- obj.to_binary_s.must_equal_binary ""
31
+ _(obj).must_equal "123"
32
+ _(obj.to_binary_s).must_equal_binary ""
33
33
  end
34
34
 
35
35
  it "accepts BinData::BasePrimitive parameters" do
36
36
  count = BinData::CountBytesRemaining.new(assert: 2)
37
- lambda {
37
+ _ {
38
38
  count.read("xyz")
39
39
  }.must_raise BinData::ValidityError
40
40
  end
@@ -6,26 +6,26 @@ describe BinData::DelayedIO, "when instantiating" do
6
6
  describe "with no mandatory parameters supplied" do
7
7
  it "raises an error" do
8
8
  args = {}
9
- lambda { BinData::DelayedIO.new(args) }.must_raise ArgumentError
9
+ _ { BinData::DelayedIO.new(args) }.must_raise ArgumentError
10
10
  end
11
11
  end
12
12
 
13
13
  describe "with some but not all mandatory parameters supplied" do
14
14
  it "raises an error" do
15
15
  args = {read_abs_offset: 3}
16
- lambda { BinData::DelayedIO.new(args) }.must_raise ArgumentError
16
+ _ { BinData::DelayedIO.new(args) }.must_raise ArgumentError
17
17
  end
18
18
  end
19
19
 
20
20
  it "fails if a given type is unknown" do
21
21
  args = {type: :does_not_exist, length: 3}
22
- lambda { BinData::DelayedIO.new(args) }.must_raise BinData::UnRegisteredTypeError
22
+ _ { BinData::DelayedIO.new(args) }.must_raise BinData::UnRegisteredTypeError
23
23
  end
24
24
 
25
25
  it "accepts BinData::Base as :type" do
26
26
  obj = BinData::Int8.new(initial_value: 5)
27
27
  array = BinData::DelayedIO.new(type: obj, read_abs_offset: 3)
28
- array.must_equal 5
28
+ _(array).must_equal 5
29
29
  end
30
30
  end
31
31
 
@@ -39,7 +39,7 @@ describe BinData::DelayedIO, "subclassed with a single type" do
39
39
 
40
40
  it "behaves as type" do
41
41
  obj = IntDelayedIO.new(3)
42
- obj.must_equal 3
42
+ _(obj).must_equal 3
43
43
  end
44
44
 
45
45
  it "does not read" do
@@ -49,37 +49,37 @@ describe BinData::DelayedIO, "subclassed with a single type" do
49
49
 
50
50
  it "does not do_num_bytes" do
51
51
  obj = IntDelayedIO.new(3)
52
- obj.do_num_bytes.must_equal 0
52
+ _(obj.do_num_bytes).must_equal 0
53
53
  end
54
54
 
55
55
  it "does num_bytes" do
56
56
  obj = IntDelayedIO.new(3)
57
- obj.num_bytes.must_equal 2
57
+ _(obj.num_bytes).must_equal 2
58
58
  end
59
59
 
60
60
  it "does not write" do
61
61
  io = StringIO.new
62
62
  obj = IntDelayedIO.new(3)
63
63
  obj.write(io)
64
- io.value.must_equal ""
64
+ _(io.value).must_equal ""
65
65
  end
66
66
 
67
67
  it "uses read_abs_offset" do
68
68
  obj = IntDelayedIO.new(3)
69
- obj.abs_offset.must_equal 5
70
- obj.rel_offset.must_equal 5
69
+ _(obj.abs_offset).must_equal 5
70
+ _(obj.rel_offset).must_equal 5
71
71
  end
72
72
 
73
73
  it "uses abs_offset if set" do
74
74
  obj = IntDelayedIO.new(3)
75
75
  obj.abs_offset = 10
76
- obj.abs_offset.must_equal 10
77
- obj.rel_offset.must_equal 10
76
+ _(obj.abs_offset).must_equal 10
77
+ _(obj.rel_offset).must_equal 10
78
78
  end
79
79
 
80
80
  it "must call #read before #read_now!" do
81
81
  obj = IntDelayedIO.new(3)
82
- lambda {
82
+ _ {
83
83
  obj.read_now!
84
84
  }.must_raise IOError
85
85
  end
@@ -88,12 +88,12 @@ describe BinData::DelayedIO, "subclassed with a single type" do
88
88
  obj = IntDelayedIO.read "\001\002\003\004\005\006\007"
89
89
  obj.read_now!
90
90
 
91
- obj.must_equal 0x0607
91
+ _(obj).must_equal 0x0607
92
92
  end
93
93
 
94
94
  it "must call #write before #write_now!" do
95
95
  obj = IntDelayedIO.new(3)
96
- lambda {
96
+ _ {
97
97
  obj.write_now!
98
98
  }.must_raise IOError
99
99
  end
@@ -103,7 +103,7 @@ describe BinData::DelayedIO, "subclassed with a single type" do
103
103
  obj = IntDelayedIO.new(3)
104
104
  obj.write(io)
105
105
  obj.write_now!
106
- io.value.must_equal "\001\002\003\004\005\000\003\010\011"
106
+ _(io.value).must_equal "\001\002\003\004\005\000\003\010\011"
107
107
  end
108
108
 
109
109
  it "writes explicitly after setting abs_offset" do
@@ -113,7 +113,7 @@ describe BinData::DelayedIO, "subclassed with a single type" do
113
113
 
114
114
  obj.abs_offset = 1
115
115
  obj.write_now!
116
- io.value.must_equal "\001\000\007\004\005\006\007\010\011"
116
+ _(io.value).must_equal "\001\000\007\004\005\006\007\010\011"
117
117
  end
118
118
  end
119
119
 
@@ -128,14 +128,14 @@ describe BinData::DelayedIO, "subclassed with multiple types" do
128
128
 
129
129
  it "behaves as type" do
130
130
  obj = StringDelayedIO.new(str: "hello")
131
- obj.snapshot.must_equal({len: 5, str: "hello"})
131
+ _(obj.snapshot).must_equal({len: 5, str: "hello"})
132
132
  end
133
133
 
134
134
  it "reads explicitly" do
135
135
  obj = StringDelayedIO.read "\001\002\003\004\005\000\003abc\013"
136
136
  obj.read_now!
137
137
 
138
- obj.snapshot.must_equal({len: 3, str: "abc"})
138
+ _(obj.snapshot).must_equal({len: 3, str: "abc"})
139
139
  end
140
140
 
141
141
  it "writes explicitly" do
@@ -143,7 +143,7 @@ describe BinData::DelayedIO, "subclassed with multiple types" do
143
143
  obj = StringDelayedIO.new(str: "hello")
144
144
  obj.write(io)
145
145
  obj.write_now!
146
- io.value.must_equal "\001\002\003\004\005\000\005hello\015"
146
+ _(io.value).must_equal "\001\002\003\004\005\000\005hello\015"
147
147
  end
148
148
  end
149
149
 
@@ -162,16 +162,16 @@ describe BinData::DelayedIO, "inside a Record" do
162
162
 
163
163
  it "reads" do
164
164
  obj = DelayedIORecord.read "\x05\x00\x03\x0012345"
165
- obj.num_bytes.must_equal 2
166
- obj.snapshot.must_equal({str_length: 0, str: "", my_int: 7})
165
+ _(obj.num_bytes).must_equal 2
166
+ _(obj.snapshot).must_equal({str_length: 0, str: "", my_int: 7})
167
167
  end
168
168
 
169
169
  it "reads explicitly" do
170
170
  obj = DelayedIORecord.read "\x05\x00\x03\x0012345"
171
171
  obj.str.read_now!
172
172
  obj.my_int.read_now!
173
- obj.num_bytes.must_equal 2
174
- obj.snapshot.must_equal({str_length: 5, str: "12345", my_int: 3})
173
+ _(obj.num_bytes).must_equal 2
174
+ _(obj.snapshot).must_equal({str_length: 5, str: "12345", my_int: 3})
175
175
  end
176
176
 
177
177
  it "writes" do
@@ -180,7 +180,52 @@ describe BinData::DelayedIO, "inside a Record" do
180
180
  obj.write(io)
181
181
  obj.str.write_now!
182
182
  obj.my_int.write_now!
183
- io.value.must_equal "\x03\x00\x02\x00abc"
183
+ _(io.value).must_equal "\x03\x00\x02\x00abc"
184
+ end
185
+ end
186
+
187
+ describe BinData::DelayedIO, "inside a Record with onlyif" do
188
+ class DelayedIOOnlyIfRecord < BinData::Record
189
+ endian :little
190
+
191
+ uint8 :flag
192
+ delayed_io :my_int1, read_abs_offset: 4, onlyif: -> { flag != 0 } do
193
+ uint16 initial_value: 6
194
+ end
195
+ delayed_io :my_int2, read_abs_offset: 2, onlyif: -> { flag == 0 } do
196
+ uint16 initial_value: 7
197
+ end
198
+ end
199
+
200
+ it "reads" do
201
+ obj = DelayedIOOnlyIfRecord.read "\x01\x00\x03\x0012345"
202
+ _(obj.num_bytes).must_equal 1
203
+ _(obj.snapshot).must_equal({flag: 1, my_int1: 6})
204
+ end
205
+
206
+ it "reads explicitly when flag is set" do
207
+ obj = DelayedIOOnlyIfRecord.read "\x01\xff\x01\x00\x02\x00"
208
+ obj.my_int1.read_now!
209
+ obj.my_int2.read_now!
210
+ _(obj.num_bytes).must_equal 1
211
+ _(obj.snapshot).must_equal({flag: 1, my_int1: 2})
212
+ end
213
+
214
+ it "reads explicitly when flag is not set" do
215
+ obj = DelayedIOOnlyIfRecord.read "\x00\xff\x01\x00\x02\x00"
216
+ obj.my_int1.read_now!
217
+ obj.my_int2.read_now!
218
+ _(obj.num_bytes).must_equal 1
219
+ _(obj.snapshot).must_equal({flag: 0, my_int2: 1})
220
+ end
221
+
222
+ it "writes" do
223
+ obj = DelayedIOOnlyIfRecord.new(flag:1, my_int1: 3, my_int2: 4)
224
+ io = StringIO.new
225
+ obj.write(io)
226
+ obj.my_int1.write_now!
227
+ obj.my_int2.write_now!
228
+ _(io.value).must_equal "\x01\x00\x00\x00\x03\x00"
184
229
  end
185
230
  end
186
231
 
@@ -195,29 +240,45 @@ describe BinData::DelayedIO, "with auto_call" do
195
240
 
196
241
  it "class reads" do
197
242
  obj = AutoCallDelayedIORecord.read "\x01\x02"
198
- obj.snapshot.must_equal({a: 1, b: 2})
243
+ _(obj.snapshot).must_equal({a: 1, b: 2})
199
244
  end
200
245
 
201
246
  it "reads" do
202
247
  obj = AutoCallDelayedIORecord.new
203
248
  obj.read "\x01\x02"
204
- obj.snapshot.must_equal({a: 1, b: 2})
249
+ _(obj.snapshot).must_equal({a: 1, b: 2})
205
250
  end
206
251
 
207
252
  it "writes" do
208
253
  obj = AutoCallDelayedIORecord.new(a: 1, b: 2)
209
254
  io = StringIO.new
210
255
  obj.write(io)
211
- io.value.must_equal "\x01\x02"
256
+ _(io.value).must_equal "\x01\x02"
212
257
  end
213
258
 
214
259
  it "to_binary_s" do
215
260
  obj = AutoCallDelayedIORecord.new(a: 1, b: 2)
216
- obj.to_binary_s.must_equal_binary "\x01\x02"
261
+ _(obj.to_binary_s).must_equal_binary "\x01\x02"
217
262
  end
218
263
 
219
264
  it "num_bytes" do
220
265
  obj = AutoCallDelayedIORecord.new(a: 1, b: 2)
221
- obj.num_bytes.must_equal 2
266
+ _(obj.num_bytes).must_equal 2
267
+ end
268
+ end
269
+
270
+ describe BinData::DelayedIO, "with multiple auto_call" do
271
+ class MultipleAutoCallDelayedIORecord < BinData::Record
272
+ auto_call_delayed_io
273
+ auto_call_delayed_io
274
+ uint8 :a
275
+ delayed_io :b, read_abs_offset: 1 do
276
+ uint8
277
+ end
278
+ end
279
+
280
+ it "class reads" do
281
+ obj = MultipleAutoCallDelayedIORecord.read "\x01\x02"
282
+ _(obj.snapshot).must_equal({a: 1, b: 2})
222
283
  end
223
284
  end