bindata 2.4.10 → 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 +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/test/registry_test.rb
CHANGED
@@ -14,14 +14,14 @@ describe BinData::Registry do
|
|
14
14
|
r.register('ASubClass', A)
|
15
15
|
r.register('AnotherSubClass', B)
|
16
16
|
|
17
|
-
r.lookup('ASubClass').must_equal A
|
18
|
-
r.lookup('a_sub_class').must_equal A
|
19
|
-
r.lookup('AnotherSubClass').must_equal B
|
20
|
-
r.lookup('another_sub_class').must_equal B
|
17
|
+
_(r.lookup('ASubClass')).must_equal A
|
18
|
+
_(r.lookup('a_sub_class')).must_equal A
|
19
|
+
_(r.lookup('AnotherSubClass')).must_equal B
|
20
|
+
_(r.lookup('another_sub_class')).must_equal B
|
21
21
|
end
|
22
22
|
|
23
23
|
it "does not lookup unregistered names" do
|
24
|
-
|
24
|
+
_ {
|
25
25
|
r.lookup('a_non_existent_sub_class')
|
26
26
|
}.must_raise BinData::UnRegisteredTypeError
|
27
27
|
end
|
@@ -30,34 +30,34 @@ describe BinData::Registry do
|
|
30
30
|
r.register('ASubClass', A)
|
31
31
|
r.unregister('ASubClass')
|
32
32
|
|
33
|
-
|
33
|
+
_ {
|
34
34
|
r.lookup('ASubClass')
|
35
35
|
}.must_raise BinData::UnRegisteredTypeError
|
36
36
|
end
|
37
37
|
|
38
38
|
it "allows overriding of registered classes" do
|
39
|
-
w, $-w = $-w,
|
39
|
+
w, $-w = $-w, nil # disable warning
|
40
40
|
|
41
41
|
begin
|
42
42
|
r.register('A', A)
|
43
43
|
r.register('A', B)
|
44
44
|
|
45
|
-
r.lookup('a').must_equal B
|
45
|
+
_(r.lookup('a')).must_equal B
|
46
46
|
ensure
|
47
47
|
$-w = w
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
it "converts CamelCase to underscores" do
|
52
|
-
r.underscore_name('CamelCase').must_equal 'camel_case'
|
52
|
+
_(r.underscore_name('CamelCase')).must_equal 'camel_case'
|
53
53
|
end
|
54
54
|
|
55
55
|
it "converts adjacent caps camelCase to underscores" do
|
56
|
-
r.underscore_name('XYZCamelCase').must_equal 'xyz_camel_case'
|
56
|
+
_(r.underscore_name('XYZCamelCase')).must_equal 'xyz_camel_case'
|
57
57
|
end
|
58
58
|
|
59
59
|
it "ignores the outer nestings of classes" do
|
60
|
-
r.underscore_name('A::B::C').must_equal 'c'
|
60
|
+
_(r.underscore_name('A::B::C')).must_equal 'c'
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -65,14 +65,14 @@ describe BinData::Registry, "with numerics" do
|
|
65
65
|
let(:r) { BinData::RegisteredClasses }
|
66
66
|
|
67
67
|
it "lookup integers with endian" do
|
68
|
-
r.lookup("int24", {endian: :big}).to_s.must_equal "BinData::Int24be"
|
69
|
-
r.lookup("int24", {endian: :little}).to_s.must_equal "BinData::Int24le"
|
70
|
-
r.lookup("uint24", {endian: :big}).to_s.must_equal "BinData::Uint24be"
|
71
|
-
r.lookup("uint24", {endian: :little}).to_s.must_equal "BinData::Uint24le"
|
68
|
+
_(r.lookup("int24", {endian: :big}).to_s).must_equal "BinData::Int24be"
|
69
|
+
_(r.lookup("int24", {endian: :little}).to_s).must_equal "BinData::Int24le"
|
70
|
+
_(r.lookup("uint24", {endian: :big}).to_s).must_equal "BinData::Uint24be"
|
71
|
+
_(r.lookup("uint24", {endian: :little}).to_s).must_equal "BinData::Uint24le"
|
72
72
|
end
|
73
73
|
|
74
74
|
it "does not lookup integers without endian" do
|
75
|
-
|
75
|
+
_ {
|
76
76
|
r.lookup("int24")
|
77
77
|
}.must_raise BinData::UnRegisteredTypeError
|
78
78
|
end
|
@@ -81,47 +81,47 @@ describe BinData::Registry, "with numerics" do
|
|
81
81
|
begin
|
82
82
|
r.lookup("int24")
|
83
83
|
rescue BinData::UnRegisteredTypeError => e
|
84
|
-
e.message.must_equal "int24, do you need to specify endian?"
|
84
|
+
_(e.message).must_equal "int24, do you need to specify endian?"
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
88
|
it "does not lookup non byte based integers" do
|
89
|
-
|
89
|
+
_ {
|
90
90
|
r.lookup("int3")
|
91
91
|
}.must_raise BinData::UnRegisteredTypeError
|
92
|
-
|
92
|
+
_ {
|
93
93
|
r.lookup("int3", {endian: :big})
|
94
94
|
}.must_raise BinData::UnRegisteredTypeError
|
95
|
-
|
95
|
+
_ {
|
96
96
|
r.lookup("int3", {endian: :little})
|
97
97
|
}.must_raise BinData::UnRegisteredTypeError
|
98
98
|
end
|
99
99
|
|
100
100
|
it "lookup floats with endian" do
|
101
|
-
r.lookup("float", {endian: :big}).to_s.must_equal "BinData::FloatBe"
|
102
|
-
r.lookup("float", {endian: :little}).to_s.must_equal "BinData::FloatLe"
|
103
|
-
r.lookup("double", {endian: :big}).to_s.must_equal "BinData::DoubleBe"
|
104
|
-
r.lookup("double", {endian: :little}).to_s.must_equal "BinData::DoubleLe"
|
101
|
+
_(r.lookup("float", {endian: :big}).to_s).must_equal "BinData::FloatBe"
|
102
|
+
_(r.lookup("float", {endian: :little}).to_s).must_equal "BinData::FloatLe"
|
103
|
+
_(r.lookup("double", {endian: :big}).to_s).must_equal "BinData::DoubleBe"
|
104
|
+
_(r.lookup("double", {endian: :little}).to_s).must_equal "BinData::DoubleLe"
|
105
105
|
end
|
106
106
|
|
107
107
|
it "lookup bits" do
|
108
|
-
r.lookup("bit5").to_s.must_equal "BinData::Bit5"
|
109
|
-
r.lookup("sbit5").to_s.must_equal "BinData::Sbit5"
|
110
|
-
r.lookup("bit6le").to_s.must_equal "BinData::Bit6le"
|
108
|
+
_(r.lookup("bit5").to_s).must_equal "BinData::Bit5"
|
109
|
+
_(r.lookup("sbit5").to_s).must_equal "BinData::Sbit5"
|
110
|
+
_(r.lookup("bit6le").to_s).must_equal "BinData::Bit6le"
|
111
111
|
end
|
112
112
|
|
113
113
|
it "lookup bits by ignoring endian" do
|
114
|
-
r.lookup("bit2", {endian: :big}).to_s.must_equal "BinData::Bit2"
|
115
|
-
r.lookup("bit3le", {endian: :big}).to_s.must_equal "BinData::Bit3le"
|
116
|
-
r.lookup("bit2", {endian: :little}).to_s.must_equal "BinData::Bit2"
|
117
|
-
r.lookup("bit3le", {endian: :little}).to_s.must_equal "BinData::Bit3le"
|
114
|
+
_(r.lookup("bit2", {endian: :big}).to_s).must_equal "BinData::Bit2"
|
115
|
+
_(r.lookup("bit3le", {endian: :big}).to_s).must_equal "BinData::Bit3le"
|
116
|
+
_(r.lookup("bit2", {endian: :little}).to_s).must_equal "BinData::Bit2"
|
117
|
+
_(r.lookup("bit3le", {endian: :little}).to_s).must_equal "BinData::Bit3le"
|
118
118
|
end
|
119
119
|
|
120
120
|
it "lookup signed bits by ignoring endian" do
|
121
|
-
r.lookup("sbit2", {endian: :big}).to_s.must_equal "BinData::Sbit2"
|
122
|
-
r.lookup("sbit3le", {endian: :big}).to_s.must_equal "BinData::Sbit3le"
|
123
|
-
r.lookup("sbit2", {endian: :little}).to_s.must_equal "BinData::Sbit2"
|
124
|
-
r.lookup("sbit3le", {endian: :little}).to_s.must_equal "BinData::Sbit3le"
|
121
|
+
_(r.lookup("sbit2", {endian: :big}).to_s).must_equal "BinData::Sbit2"
|
122
|
+
_(r.lookup("sbit3le", {endian: :big}).to_s).must_equal "BinData::Sbit3le"
|
123
|
+
_(r.lookup("sbit2", {endian: :little}).to_s).must_equal "BinData::Sbit2"
|
124
|
+
_(r.lookup("sbit3le", {endian: :little}).to_s).must_equal "BinData::Sbit3le"
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -134,15 +134,15 @@ describe BinData::Registry, "with endian specific types" do
|
|
134
134
|
end
|
135
135
|
|
136
136
|
it "lookup little endian types" do
|
137
|
-
r.lookup('a', {endian: :little}).must_equal A
|
137
|
+
_(r.lookup('a', {endian: :little})).must_equal A
|
138
138
|
end
|
139
139
|
|
140
140
|
it "lookup big endian types" do
|
141
|
-
r.lookup('b', {endian: :big}).must_equal B
|
141
|
+
_(r.lookup('b', {endian: :big})).must_equal B
|
142
142
|
end
|
143
143
|
|
144
144
|
it "does not lookup types with non existent endian" do
|
145
|
-
|
145
|
+
_ {
|
146
146
|
r.lookup('a', {endian: :big})
|
147
147
|
}.must_raise BinData::UnRegisteredTypeError
|
148
148
|
end
|
@@ -151,7 +151,7 @@ describe BinData::Registry, "with endian specific types" do
|
|
151
151
|
r.register('c', C)
|
152
152
|
r.register('c_le', D)
|
153
153
|
|
154
|
-
r.lookup('c', {endian: :little}).must_equal C
|
154
|
+
_(r.lookup('c', {endian: :little})).must_equal C
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
@@ -164,18 +164,18 @@ describe BinData::Registry, "with search_prefix" do
|
|
164
164
|
end
|
165
165
|
|
166
166
|
it "lookup single search_prefix" do
|
167
|
-
r.lookup('f', {search_prefix: :a}).must_equal A
|
167
|
+
_(r.lookup('f', {search_prefix: :a})).must_equal A
|
168
168
|
end
|
169
169
|
|
170
170
|
it "lookup single search_prefix with endian" do
|
171
|
-
r.lookup('f', {search_prefix: :a, endian: :little}).must_equal A
|
171
|
+
_(r.lookup('f', {search_prefix: :a, endian: :little})).must_equal A
|
172
172
|
end
|
173
173
|
|
174
174
|
it "lookup multiple search_prefix" do
|
175
|
-
r.lookup('f', {search_prefix: [:x, :a]}).must_equal A
|
175
|
+
_(r.lookup('f', {search_prefix: [:x, :a]})).must_equal A
|
176
176
|
end
|
177
177
|
|
178
178
|
it "lookup first match in search_prefix" do
|
179
|
-
r.lookup('f', {search_prefix: [:a, :b]}).must_equal A
|
179
|
+
_(r.lookup('f', {search_prefix: [:a, :b]})).must_equal A
|
180
180
|
end
|
181
181
|
end
|
data/test/rest_test.rb
CHANGED
@@ -6,23 +6,23 @@ describe BinData::Rest do
|
|
6
6
|
let(:obj) { BinData::Rest.new }
|
7
7
|
|
8
8
|
it "initial state" do
|
9
|
-
obj.must_equal ""
|
9
|
+
_(obj).must_equal ""
|
10
10
|
end
|
11
11
|
|
12
12
|
it "reads till end of stream" do
|
13
13
|
data = "abcdefghij"
|
14
|
-
obj.read(data).must_equal data
|
14
|
+
_(obj.read(data)).must_equal data
|
15
15
|
end
|
16
16
|
|
17
17
|
it "allows setting value for completeness" do
|
18
18
|
obj.assign("123")
|
19
|
-
obj.must_equal "123"
|
20
|
-
obj.to_binary_s.must_equal_binary "123"
|
19
|
+
_(obj).must_equal "123"
|
20
|
+
_(obj.to_binary_s).must_equal_binary "123"
|
21
21
|
end
|
22
22
|
|
23
23
|
it "accepts BinData::BasePrimitive parameters" do
|
24
24
|
rest = BinData::Rest.new(assert: "abc")
|
25
|
-
|
25
|
+
_ {
|
26
26
|
rest.read("xyz")
|
27
27
|
}.must_raise BinData::ValidityError
|
28
28
|
end
|
@@ -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
@@ -6,7 +6,7 @@ describe BinData::Skip, "when instantiating" do
|
|
6
6
|
describe "with no mandatory parameters supplied" do
|
7
7
|
it "raises an error" do
|
8
8
|
args = {}
|
9
|
-
|
9
|
+
_ { BinData::Skip.new(args) }.must_raise ArgumentError
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -16,23 +16,23 @@ describe BinData::Skip, "with :length" do
|
|
16
16
|
let(:io) { StringIO.new("abcdefghij") }
|
17
17
|
|
18
18
|
it "initial state" do
|
19
|
-
obj.must_equal ""
|
20
|
-
obj.to_binary_s.must_equal_binary "\000" * 5
|
19
|
+
_(obj).must_equal ""
|
20
|
+
_(obj.to_binary_s).must_equal_binary "\000" * 5
|
21
21
|
end
|
22
22
|
|
23
23
|
it "skips bytes" do
|
24
24
|
obj.read(io)
|
25
|
-
io.pos.must_equal 5
|
25
|
+
_(io.pos).must_equal 5
|
26
26
|
end
|
27
27
|
|
28
28
|
it "has expected binary representation after setting value" do
|
29
29
|
obj.assign("123")
|
30
|
-
obj.to_binary_s.must_equal_binary "\000" * 5
|
30
|
+
_(obj.to_binary_s).must_equal_binary "\000" * 5
|
31
31
|
end
|
32
32
|
|
33
33
|
it "has expected binary representation after reading" do
|
34
34
|
obj.read(io)
|
35
|
-
obj.to_binary_s.must_equal_binary "\000" * 5
|
35
|
+
_(obj.to_binary_s).must_equal_binary "\000" * 5
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -46,55 +46,75 @@ describe BinData::Skip, "with :to_abs_offset" do
|
|
46
46
|
fields = [ skip_obj ]
|
47
47
|
obj = BinData::Struct.new(fields: fields)
|
48
48
|
obj.read(io)
|
49
|
-
io.pos.must_equal 5
|
49
|
+
_(io.pos).must_equal 5
|
50
50
|
end
|
51
51
|
|
52
52
|
it "reads skipping in place" do
|
53
53
|
fields = [ [:string, :a, { read_length: 5 }], skip_obj ]
|
54
54
|
obj = BinData::Struct.new(fields: fields)
|
55
55
|
obj.read(io)
|
56
|
-
io.pos.must_equal 5
|
56
|
+
_(io.pos).must_equal 5
|
57
57
|
end
|
58
58
|
|
59
59
|
it "does not read skipping backwards" do
|
60
60
|
fields = [ [:string, :a, { read_length: 10 }], skip_obj ]
|
61
61
|
obj = BinData::Struct.new(fields: fields)
|
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
|
69
69
|
fields = [ skip_obj ]
|
70
70
|
obj = BinData::Struct.new(fields: fields)
|
71
|
-
obj.to_binary_s.must_equal "\000\000\000\000\000"
|
71
|
+
_(obj.to_binary_s).must_equal "\000\000\000\000\000"
|
72
72
|
end
|
73
73
|
|
74
74
|
it "reads skipping in place" do
|
75
75
|
fields = [ [:string, :a, { value: "abcde" }], skip_obj ]
|
76
76
|
obj = BinData::Struct.new(fields: fields)
|
77
|
-
obj.to_binary_s.must_equal "abcde"
|
77
|
+
_(obj.to_binary_s).must_equal "abcde"
|
78
78
|
end
|
79
79
|
|
80
80
|
it "does not write skipping backwards" do
|
81
81
|
fields = [ [:string, :a, { value: "abcdefghij" }], skip_obj ]
|
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 }] ]
|
95
102
|
obj = BinData::Struct.new(fields: fields)
|
96
103
|
obj.read(io)
|
97
|
-
io.pos.must_equal 5
|
104
|
+
_(io.pos).must_equal 5
|
105
|
+
end
|
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
|
98
118
|
end
|
99
119
|
|
100
120
|
it "doesn't skip when validator doesn't assert" do
|
@@ -102,36 +122,61 @@ describe BinData::Skip, "with :until_valid" do
|
|
102
122
|
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
103
123
|
obj = BinData::Struct.new(fields: fields)
|
104
124
|
obj.read(io)
|
105
|
-
io.pos.must_equal 0
|
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
|
118
138
|
skip_obj = [:string, { read_length: 30 }]
|
119
139
|
fields = [ [:skip, :s, { until_valid: skip_obj }] ]
|
120
140
|
obj = BinData::Struct.new(fields: fields)
|
121
|
-
|
141
|
+
_ {
|
122
142
|
obj.read(io)
|
123
143
|
}.must_raise IOError
|
124
144
|
end
|
125
145
|
|
126
|
-
|
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
|
152
|
+
end
|
153
|
+
|
154
|
+
obj = DSLSkip.read(io)
|
155
|
+
_(obj.a).must_equal "f"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe BinData::Skip, "with :until_valid" do
|
160
|
+
class SkipSearch < BinData::Record
|
127
161
|
skip :s do
|
128
|
-
|
162
|
+
uint8
|
163
|
+
uint8 asserted_value: 1
|
164
|
+
uint8 :a
|
165
|
+
uint8 :b
|
166
|
+
virtual assert: -> { a == b }
|
129
167
|
end
|
130
|
-
|
168
|
+
array :data, type: :uint8, initial_length: 4
|
131
169
|
end
|
132
170
|
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
136
181
|
end
|
137
182
|
end
|