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/test/array_test.rb
CHANGED
@@ -18,17 +18,15 @@ describe BinData::Array, "when instantiating" do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "warns about :length" do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
_ {
|
22
|
+
BinData::Array.new(type: :uint8, length: 3)
|
23
|
+
}.must_warn ":length is not used with BinData::Array. You probably want to change this to :initial_length"
|
25
24
|
end
|
26
25
|
|
27
26
|
it "warns about :read_length" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
27
|
+
_ {
|
28
|
+
BinData::Array.new(type: :uint8, read_length: 3)
|
29
|
+
}.must_warn ":read_length is not used with BinData::Array. You probably want to change this to :initial_length"
|
32
30
|
end
|
33
31
|
|
34
32
|
it "fails if a given type is unknown" do
|
@@ -71,6 +69,10 @@ describe BinData::Array, "with no elements" do
|
|
71
69
|
it "returns [] for the last n elements" do
|
72
70
|
_(obj.last(3)).must_equal []
|
73
71
|
end
|
72
|
+
|
73
|
+
it "won't assign nil" do
|
74
|
+
_ { obj.assign(nil) }.must_raise ArgumentError
|
75
|
+
end
|
74
76
|
end
|
75
77
|
|
76
78
|
describe BinData::Array, "with several elements" do
|
data/test/buffer_test.rb
CHANGED
@@ -144,6 +144,15 @@ describe BinData::Buffer, "nested buffers" do
|
|
144
144
|
_(obj.b).must_equal "klmno"
|
145
145
|
end
|
146
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"
|
154
|
+
end
|
155
|
+
|
147
156
|
it "restricts oversize writes" do
|
148
157
|
obj = NestedBufferRecord.new
|
149
158
|
obj.a.aa = "abcdefghij"
|
data/test/choice_test.rb
CHANGED
@@ -243,7 +243,7 @@ describe BinData::Choice, "subclassed with default parameters" do
|
|
243
243
|
_(obj.num_bytes).must_equal 2
|
244
244
|
end
|
245
245
|
|
246
|
-
it "
|
246
|
+
it "overrides default parameter" do
|
247
247
|
obj = DerivedChoice.new(selection: 'b')
|
248
248
|
_(obj.num_bytes).must_equal 4
|
249
249
|
end
|
data/test/delayed_io_test.rb
CHANGED
@@ -266,3 +266,19 @@ describe BinData::DelayedIO, "with auto_call" do
|
|
266
266
|
_(obj.num_bytes).must_equal 2
|
267
267
|
end
|
268
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})
|
283
|
+
end
|
284
|
+
end
|
data/test/io_test.rb
CHANGED
@@ -15,16 +15,24 @@ describe BinData::IO::Read, "reading from non seekable stream" do
|
|
15
15
|
@rd.close
|
16
16
|
end
|
17
17
|
|
18
|
-
it "
|
19
|
-
@io.
|
20
|
-
_(@io.
|
18
|
+
it "seeks correctly" do
|
19
|
+
@io.skipbytes(1999)
|
20
|
+
_(@io.readbytes(5)).must_equal "abbbb"
|
21
21
|
end
|
22
22
|
|
23
|
-
it "seeks
|
24
|
-
@io.
|
23
|
+
it "seeks to abs_offset" do
|
24
|
+
@io.skipbytes(1000)
|
25
|
+
@io.seek_to_abs_offset(1999)
|
25
26
|
_(@io.readbytes(5)).must_equal "abbbb"
|
26
27
|
end
|
27
28
|
|
29
|
+
it "wont seek backwards" do
|
30
|
+
@io.skipbytes(5)
|
31
|
+
_ {
|
32
|
+
@io.skipbytes(-1)
|
33
|
+
}.must_raise IOError
|
34
|
+
end
|
35
|
+
|
28
36
|
it "#num_bytes_remaining raises IOError" do
|
29
37
|
_ {
|
30
38
|
@io.num_bytes_remaining
|
@@ -32,6 +40,35 @@ describe BinData::IO::Read, "reading from non seekable stream" do
|
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
43
|
+
describe BinData::IO::Write, "writing to non seekable stream" do
|
44
|
+
before do
|
45
|
+
@rd, @wr = IO::pipe
|
46
|
+
@io = BinData::IO::Write.new(@wr)
|
47
|
+
end
|
48
|
+
|
49
|
+
after do
|
50
|
+
@rd.close
|
51
|
+
@wr.close
|
52
|
+
end
|
53
|
+
|
54
|
+
def written_data
|
55
|
+
@io.flush
|
56
|
+
@wr.close
|
57
|
+
@rd.read
|
58
|
+
end
|
59
|
+
|
60
|
+
it "writes correctly" do
|
61
|
+
@io.writebytes("hello")
|
62
|
+
_(written_data).must_equal "hello"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "must not attempt to seek" do
|
66
|
+
_ {
|
67
|
+
@io.seek_to_abs_offset(5)
|
68
|
+
}.must_raise IOError
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
35
72
|
describe BinData::IO::Read, "when reading" do
|
36
73
|
let(:stream) { StringIO.new "abcdefghij" }
|
37
74
|
let(:io) { BinData::IO::Read.new(stream) }
|
@@ -42,19 +79,19 @@ describe BinData::IO::Read, "when reading" do
|
|
42
79
|
}.must_raise ArgumentError
|
43
80
|
end
|
44
81
|
|
45
|
-
it "returns correct offset" do
|
46
|
-
stream.seek(3, IO::SEEK_CUR)
|
47
|
-
|
48
|
-
_(io.offset).must_equal 0
|
49
|
-
_(io.readbytes(4)).must_equal "defg"
|
50
|
-
_(io.offset).must_equal 4
|
51
|
-
end
|
52
|
-
|
53
82
|
it "seeks correctly" do
|
54
|
-
io.
|
83
|
+
io.skipbytes(2)
|
55
84
|
_(io.readbytes(4)).must_equal "cdef"
|
56
85
|
end
|
57
86
|
|
87
|
+
it "wont seek backwards" do
|
88
|
+
io.skipbytes(5)
|
89
|
+
_ {
|
90
|
+
io.skipbytes(-1)
|
91
|
+
}.must_raise IOError
|
92
|
+
end
|
93
|
+
|
94
|
+
|
58
95
|
it "reads all bytes" do
|
59
96
|
_(io.read_all_bytes).must_equal "abcdefghij"
|
60
97
|
end
|
@@ -67,7 +104,7 @@ describe BinData::IO::Read, "when reading" do
|
|
67
104
|
end
|
68
105
|
|
69
106
|
it "raises error when reading at eof" do
|
70
|
-
io.
|
107
|
+
io.skipbytes(10)
|
71
108
|
_ {
|
72
109
|
io.readbytes(3)
|
73
110
|
}.must_raise EOFError
|
@@ -80,149 +117,6 @@ describe BinData::IO::Read, "when reading" do
|
|
80
117
|
end
|
81
118
|
end
|
82
119
|
|
83
|
-
describe BinData::IO::Read, "#with_buffer" do
|
84
|
-
let(:stream) { StringIO.new "abcdefghijklmnopqrst" }
|
85
|
-
let(:io) { BinData::IO::Read.new(stream) }
|
86
|
-
|
87
|
-
it "consumes entire buffer on short reads" do
|
88
|
-
io.with_buffer(10) do
|
89
|
-
_(io.readbytes(4)).must_equal "abcd"
|
90
|
-
end
|
91
|
-
_(io.offset).must_equal(10)
|
92
|
-
end
|
93
|
-
|
94
|
-
it "consumes entire buffer on read_all_bytes" do
|
95
|
-
io.with_buffer(10) do
|
96
|
-
_(io.read_all_bytes).must_equal "abcdefghij"
|
97
|
-
end
|
98
|
-
_(io.offset).must_equal(10)
|
99
|
-
end
|
100
|
-
|
101
|
-
it "restricts large reads" do
|
102
|
-
io.with_buffer(10) do
|
103
|
-
_ {
|
104
|
-
io.readbytes(15)
|
105
|
-
}.must_raise IOError
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
it "is nestable" do
|
110
|
-
io.with_buffer(10) do
|
111
|
-
_(io.readbytes(2)).must_equal "ab"
|
112
|
-
io.with_buffer(5) do
|
113
|
-
_(io.read_all_bytes).must_equal "cdefg"
|
114
|
-
end
|
115
|
-
_(io.offset).must_equal(2 + 5)
|
116
|
-
end
|
117
|
-
_(io.offset).must_equal(10)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "restricts large nested buffers" do
|
121
|
-
io.with_buffer(10) do
|
122
|
-
_(io.readbytes(2)).must_equal "ab"
|
123
|
-
io.with_buffer(20) do
|
124
|
-
_(io.read_all_bytes).must_equal "cdefghij"
|
125
|
-
_(io.offset).must_equal(10)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
_(io.offset).must_equal(10)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "restricts large seeks" do
|
132
|
-
io.with_buffer(10) do
|
133
|
-
io.seekbytes(15)
|
134
|
-
end
|
135
|
-
_(io.offset).must_equal(10)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "restricts large -ve seeks" do
|
139
|
-
io.readbytes(2)
|
140
|
-
io.with_buffer(10) do
|
141
|
-
io.seekbytes(-1)
|
142
|
-
_(io.offset).must_equal(2)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
it "greater than stream size consumes all bytes" do
|
147
|
-
io.with_buffer(30) do
|
148
|
-
_(io.readbytes(4)).must_equal "abcd"
|
149
|
-
end
|
150
|
-
_(io.offset).must_equal(20)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "restricts #num_bytes_remaining" do
|
154
|
-
io.with_buffer(10) do
|
155
|
-
io.readbytes(2)
|
156
|
-
_(io.num_bytes_remaining).must_equal 8
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
it "greater than stream size doesn't restrict #num_bytes_remaining" do
|
161
|
-
io.with_buffer(30) do
|
162
|
-
io.readbytes(2)
|
163
|
-
_(io.num_bytes_remaining).must_equal 18
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
module IOReadWithReadahead
|
169
|
-
def test_rolls_back_short_reads
|
170
|
-
_(io.readbytes(2)).must_equal "ab"
|
171
|
-
io.with_readahead do
|
172
|
-
_(io.readbytes(4)).must_equal "cdef"
|
173
|
-
end
|
174
|
-
_(io.offset).must_equal 2
|
175
|
-
end
|
176
|
-
|
177
|
-
def test_rolls_back_read_all_bytes
|
178
|
-
_(io.readbytes(3)).must_equal "abc"
|
179
|
-
io.with_readahead do
|
180
|
-
_(io.read_all_bytes).must_equal "defghijklmnopqrst"
|
181
|
-
end
|
182
|
-
_(io.offset).must_equal 3
|
183
|
-
end
|
184
|
-
|
185
|
-
def test_inside_buffer_rolls_back_reads
|
186
|
-
io.with_buffer(10) do
|
187
|
-
io.with_readahead do
|
188
|
-
_(io.readbytes(4)).must_equal "abcd"
|
189
|
-
end
|
190
|
-
_(io.offset).must_equal 0
|
191
|
-
end
|
192
|
-
_(io.offset).must_equal 10
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_outside_buffer_rolls_back_reads
|
196
|
-
io.with_readahead do
|
197
|
-
io.with_buffer(10) do
|
198
|
-
_(io.readbytes(4)).must_equal "abcd"
|
199
|
-
end
|
200
|
-
_(io.offset).must_equal 10
|
201
|
-
end
|
202
|
-
_(io.offset).must_equal 0
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
describe BinData::IO::Read, "#with_readahead" do
|
207
|
-
let(:stream) { StringIO.new "abcdefghijklmnopqrst" }
|
208
|
-
let(:io) { BinData::IO::Read.new(stream) }
|
209
|
-
|
210
|
-
include IOReadWithReadahead
|
211
|
-
end
|
212
|
-
|
213
|
-
describe BinData::IO::Read, "unseekable stream #with_readahead" do
|
214
|
-
let(:stream) {
|
215
|
-
io = StringIO.new "abcdefghijklmnopqrst"
|
216
|
-
def io.pos
|
217
|
-
raise Errno::EPIPE
|
218
|
-
end
|
219
|
-
io
|
220
|
-
}
|
221
|
-
let(:io) { BinData::IO::Read.new(stream) }
|
222
|
-
|
223
|
-
include IOReadWithReadahead
|
224
|
-
end
|
225
|
-
|
226
120
|
describe BinData::IO::Write, "writing to non seekable stream" do
|
227
121
|
before do
|
228
122
|
@rd, @wr = IO::pipe
|
@@ -238,30 +132,6 @@ describe BinData::IO::Write, "writing to non seekable stream" do
|
|
238
132
|
@io.writebytes("1234567890")
|
239
133
|
_(@rd.read(10)).must_equal "1234567890"
|
240
134
|
end
|
241
|
-
|
242
|
-
it "has correct offset" do
|
243
|
-
@io.writebytes("1234567890")
|
244
|
-
_(@io.offset).must_equal 10
|
245
|
-
end
|
246
|
-
|
247
|
-
it "does not seek backwards" do
|
248
|
-
@io.writebytes("1234567890")
|
249
|
-
_ {
|
250
|
-
@io.seekbytes(-5)
|
251
|
-
}.must_raise IOError
|
252
|
-
end
|
253
|
-
|
254
|
-
it "does not seek forwards" do
|
255
|
-
_ {
|
256
|
-
@io.seekbytes(5)
|
257
|
-
}.must_raise IOError
|
258
|
-
end
|
259
|
-
|
260
|
-
it "#num_bytes_remaining raises IOError" do
|
261
|
-
_ {
|
262
|
-
@io.num_bytes_remaining
|
263
|
-
}.must_raise IOError
|
264
|
-
end
|
265
135
|
end
|
266
136
|
|
267
137
|
describe BinData::IO::Write, "when writing" do
|
@@ -280,21 +150,6 @@ describe BinData::IO::Write, "when writing" do
|
|
280
150
|
_(stream.value).must_equal "abcd"
|
281
151
|
end
|
282
152
|
|
283
|
-
it "has #offset" do
|
284
|
-
_(io.offset).must_equal 0
|
285
|
-
|
286
|
-
io.writebytes("abcd")
|
287
|
-
_(io.offset).must_equal 4
|
288
|
-
|
289
|
-
io.writebytes("ABCD")
|
290
|
-
_(io.offset).must_equal 8
|
291
|
-
end
|
292
|
-
|
293
|
-
it "rounds up #offset when writing bits" do
|
294
|
-
io.writebits(123, 9, :little)
|
295
|
-
_(io.offset).must_equal 2
|
296
|
-
end
|
297
|
-
|
298
153
|
it "flushes" do
|
299
154
|
io.writebytes("abcd")
|
300
155
|
io.flush
|
@@ -303,53 +158,6 @@ describe BinData::IO::Write, "when writing" do
|
|
303
158
|
end
|
304
159
|
end
|
305
160
|
|
306
|
-
describe BinData::IO::Write, "#with_buffer" do
|
307
|
-
let(:stream) { StringIO.new }
|
308
|
-
let(:io) { BinData::IO::Write.new(stream) }
|
309
|
-
|
310
|
-
it "pads entire buffer on short reads" do
|
311
|
-
io.with_buffer(10) do
|
312
|
-
io.writebytes "abcde"
|
313
|
-
end
|
314
|
-
|
315
|
-
_(stream.value).must_equal "abcde\0\0\0\0\0"
|
316
|
-
end
|
317
|
-
|
318
|
-
it "discards excess on large writes" do
|
319
|
-
io.with_buffer(5) do
|
320
|
-
io.writebytes "abcdefghij"
|
321
|
-
end
|
322
|
-
|
323
|
-
_(stream.value).must_equal "abcde"
|
324
|
-
end
|
325
|
-
|
326
|
-
it "is nestable" do
|
327
|
-
io.with_buffer(10) do
|
328
|
-
io.with_buffer(5) do
|
329
|
-
io.writebytes "abc"
|
330
|
-
end
|
331
|
-
io.writebytes "de"
|
332
|
-
end
|
333
|
-
|
334
|
-
_(stream.value).must_equal "abc\0\0de\0\0\0"
|
335
|
-
end
|
336
|
-
|
337
|
-
it "restricts large seeks" do
|
338
|
-
io.with_buffer(10) do
|
339
|
-
io.seekbytes(15)
|
340
|
-
end
|
341
|
-
_(io.offset).must_equal(10)
|
342
|
-
end
|
343
|
-
|
344
|
-
it "restricts large -ve seeks" do
|
345
|
-
io.writebytes("12")
|
346
|
-
io.with_buffer(10) do
|
347
|
-
io.seekbytes(-1)
|
348
|
-
_(io.offset).must_equal(2)
|
349
|
-
end
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
161
|
describe BinData::IO::Read, "reading bits in big endian" do
|
354
162
|
let(:b1) { 0b1111_1010 }
|
355
163
|
let(:b2) { 0b1100_1110 }
|
@@ -554,7 +362,7 @@ describe BinData::IO::Write, "writing bits in little endian" do
|
|
554
362
|
end
|
555
363
|
|
556
364
|
describe BinData::IO::Read, "with changing endian" do
|
557
|
-
it "does not mix different
|
365
|
+
it "does not mix different endianness when reading" do
|
558
366
|
b1 = 0b0110_1010
|
559
367
|
b2 = 0b1110_0010
|
560
368
|
str = [b1, b2].pack("CC")
|
@@ -566,7 +374,7 @@ describe BinData::IO::Read, "with changing endian" do
|
|
566
374
|
end
|
567
375
|
|
568
376
|
describe BinData::IO::Write, "with changing endian" do
|
569
|
-
it "does not mix different
|
377
|
+
it "does not mix different endianness when writing" do
|
570
378
|
io = BitWriterHelper.new
|
571
379
|
io.writebits(0b110, 3, :big)
|
572
380
|
io.writebits(0b010, 3, :little)
|
data/test/registry_test.rb
CHANGED
@@ -0,0 +1,111 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
4
|
+
|
5
|
+
describe BinData::Section do
|
6
|
+
it "transforms data byte at a time" do
|
7
|
+
require 'bindata/transform/xor'
|
8
|
+
|
9
|
+
obj = BinData::Section.new(transform: -> { BinData::Transform::Xor.new(0xff) },
|
10
|
+
type: [:string, read_length: 5])
|
11
|
+
|
12
|
+
_(obj.read("\x97\x9A\x93\x93\x90")).must_equal "hello"
|
13
|
+
end
|
14
|
+
|
15
|
+
begin
|
16
|
+
require 'brotli'
|
17
|
+
it "transform brotli" do
|
18
|
+
require 'bindata/transform/brotli'
|
19
|
+
|
20
|
+
class BrotliRecord < BinData::Record
|
21
|
+
int32le :len, value: -> { s.num_bytes }
|
22
|
+
section :s, transform: -> { BinData::Transform::Brotli.new(len) } do
|
23
|
+
int32le :str_len, value: -> { str.length }
|
24
|
+
string :str, read_length: :str_len
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
obj = BrotliRecord.new
|
30
|
+
data = "highly compressible" * 100
|
31
|
+
obj.s.str = data
|
32
|
+
_(obj.len).must_be :<, (data.length / 10)
|
33
|
+
|
34
|
+
str = obj.to_binary_s
|
35
|
+
obj = BrotliRecord.read(str)
|
36
|
+
_(obj.s.str).must_equal data
|
37
|
+
end
|
38
|
+
rescue LoadError; end
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'extlz4'
|
42
|
+
it "transform lz4" do
|
43
|
+
require 'bindata/transform/lz4'
|
44
|
+
|
45
|
+
class LZ4Record < BinData::Record
|
46
|
+
int32le :len, value: -> { s.num_bytes }
|
47
|
+
section :s, transform: -> { BinData::Transform::LZ4.new(len) } do
|
48
|
+
int32le :str_len, value: -> { str.length }
|
49
|
+
string :str, read_length: :str_len
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
obj = LZ4Record.new
|
55
|
+
data = "highly compressible" * 100
|
56
|
+
obj.s.str = data
|
57
|
+
_(obj.len).must_be :<, (data.length / 10)
|
58
|
+
|
59
|
+
str = obj.to_binary_s
|
60
|
+
obj = LZ4Record.read(str)
|
61
|
+
_(obj.s.str).must_equal data
|
62
|
+
end
|
63
|
+
rescue LoadError; end
|
64
|
+
|
65
|
+
it "transform zlib" do
|
66
|
+
require 'bindata/transform/zlib'
|
67
|
+
|
68
|
+
class ZlibRecord < BinData::Record
|
69
|
+
int32le :len, value: -> { s.num_bytes }
|
70
|
+
section :s, transform: -> { BinData::Transform::Zlib.new(len) } do
|
71
|
+
int32le :str_len, value: -> { str.length }
|
72
|
+
string :str, read_length: :str_len
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
obj = ZlibRecord.new
|
78
|
+
data = "highly compressible" * 100
|
79
|
+
obj.s.str = data
|
80
|
+
_(obj.len).must_be :<, (data.length / 10)
|
81
|
+
|
82
|
+
str = obj.to_binary_s
|
83
|
+
obj = ZlibRecord.read(str)
|
84
|
+
_(obj.s.str).must_equal data
|
85
|
+
end
|
86
|
+
|
87
|
+
begin
|
88
|
+
require 'zstd-ruby'
|
89
|
+
it "transform zstd" do
|
90
|
+
require 'bindata/transform/zstd'
|
91
|
+
|
92
|
+
class ZstdRecord < BinData::Record
|
93
|
+
int32le :len, value: -> { s.num_bytes }
|
94
|
+
section :s, transform: -> { BinData::Transform::Zstd.new(len) } do
|
95
|
+
int32le :str_len, value: -> { str.length }
|
96
|
+
string :str, read_length: :str_len
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
obj = ZstdRecord.new
|
102
|
+
data = "highly compressible" * 100
|
103
|
+
obj.s.str = data
|
104
|
+
_(obj.len).must_be :<, (data.length / 10)
|
105
|
+
|
106
|
+
str = obj.to_binary_s
|
107
|
+
obj = ZstdRecord.read(str)
|
108
|
+
_(obj.s.str).must_equal data
|
109
|
+
end
|
110
|
+
rescue LoadError; end
|
111
|
+
end
|
data/test/skip_test.rb
CHANGED
@@ -62,7 +62,7 @@ describe BinData::Skip, "with :to_abs_offset" do
|
|
62
62
|
|
63
63
|
_ {
|
64
64
|
obj.read(io)
|
65
|
-
}.must_raise
|
65
|
+
}.must_raise ArgumentError
|
66
66
|
end
|
67
67
|
|
68
68
|
it "writes skipping forward" do
|
@@ -82,13 +82,20 @@ describe BinData::Skip, "with :to_abs_offset" do
|
|
82
82
|
obj = BinData::Struct.new(fields: fields)
|
83
83
|
_ {
|
84
84
|
obj.to_binary_s
|
85
|
-
}.must_raise
|
85
|
+
}.must_raise ArgumentError
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
describe BinData::Skip, "with :until_valid" do
|
90
90
|
let(:io) { StringIO.new("abcdefghij") }
|
91
91
|
|
92
|
+
it "doesn't skip when writing" do
|
93
|
+
skip_obj = [:string, { read_length: 1, assert: "f" }]
|
94
|
+
args = { until_valid: skip_obj }
|
95
|
+
obj = BinData::Skip.new(args)
|
96
|
+
_(obj.to_binary_s).must_equal ""
|
97
|
+
end
|
98
|
+
|
92
99
|
it "skips to valid match" do
|
93
100
|
skip_obj = [:string, { read_length: 1, assert: "f" }]
|
94
101
|
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
@@ -97,6 +104,19 @@ describe BinData::Skip, "with :until_valid" do
|
|
97
104
|
_(io.pos).must_equal 5
|
98
105
|
end
|
99
106
|
|
107
|
+
it "won't skip on unseekable stream" do
|
108
|
+
rd, wr = IO::pipe
|
109
|
+
unseekable_io = BinData::IO::Read.new(rd)
|
110
|
+
wr.write io
|
111
|
+
wr.close
|
112
|
+
|
113
|
+
skip_obj = [:string, { read_length: 1, assert: "f" }]
|
114
|
+
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
115
|
+
obj = BinData::Struct.new(fields: fields)
|
116
|
+
_ {obj.read(unseekable_io)}.must_raise IOError
|
117
|
+
rd.close
|
118
|
+
end
|
119
|
+
|
100
120
|
it "doesn't skip when validator doesn't assert" do
|
101
121
|
skip_obj = [:string, { read_length: 1 }]
|
102
122
|
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
@@ -105,13 +125,13 @@ describe BinData::Skip, "with :until_valid" do
|
|
105
125
|
_(io.pos).must_equal 0
|
106
126
|
end
|
107
127
|
|
108
|
-
it "raises
|
128
|
+
it "raises IOError when no match" do
|
109
129
|
skip_obj = [:string, { read_length: 1, assert: "X" }]
|
110
130
|
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
111
131
|
obj = BinData::Struct.new(fields: fields)
|
112
132
|
_ {
|
113
133
|
obj.read(io)
|
114
|
-
}.must_raise
|
134
|
+
}.must_raise IOError
|
115
135
|
end
|
116
136
|
|
117
137
|
it "raises IOError when validator reads beyond stream" do
|
@@ -123,15 +143,40 @@ describe BinData::Skip, "with :until_valid" do
|
|
123
143
|
}.must_raise IOError
|
124
144
|
end
|
125
145
|
|
126
|
-
|
127
|
-
|
128
|
-
|
146
|
+
it "uses block form" do
|
147
|
+
class DSLSkip < BinData::Record
|
148
|
+
skip :s do
|
149
|
+
string read_length: 1, assert: "f"
|
150
|
+
end
|
151
|
+
string :a, read_length: 1
|
129
152
|
end
|
130
|
-
string :a, read_length: 1
|
131
|
-
end
|
132
153
|
|
133
|
-
it "uses block form" do
|
134
154
|
obj = DSLSkip.read(io)
|
135
155
|
_(obj.a).must_equal "f"
|
136
156
|
end
|
137
157
|
end
|
158
|
+
|
159
|
+
describe BinData::Skip, "with :until_valid" do
|
160
|
+
class SkipSearch < BinData::Record
|
161
|
+
skip :s do
|
162
|
+
uint8
|
163
|
+
uint8 asserted_value: 1
|
164
|
+
uint8 :a
|
165
|
+
uint8 :b
|
166
|
+
virtual assert: -> { a == b }
|
167
|
+
end
|
168
|
+
array :data, type: :uint8, initial_length: 4
|
169
|
+
end
|
170
|
+
|
171
|
+
let(:io) { BinData::IO.create_string_io("\x0f" * 10 + "\x00\x01\x02\x03\x00" + "\x02\x01\x03\x03" + "\x06") }
|
172
|
+
|
173
|
+
it "finds valid match" do
|
174
|
+
obj = SkipSearch.read(io)
|
175
|
+
_(obj.data).must_equal [2, 1, 3, 3]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "match is at expected offset" do
|
179
|
+
obj = SkipSearch.read(io)
|
180
|
+
_(obj.data.rel_offset).must_equal 15
|
181
|
+
end
|
182
|
+
end
|