bindata 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +11 -2
- data/README +55 -19
- data/TODO +4 -0
- data/examples/gzip.rb +3 -3
- data/lib/bindata.rb +8 -1
- data/lib/bindata/array.rb +58 -26
- data/lib/bindata/base.rb +133 -83
- data/lib/bindata/choice.rb +142 -61
- data/lib/bindata/float.rb +4 -0
- data/lib/bindata/int.rb +14 -0
- data/lib/bindata/lazy.rb +19 -2
- data/lib/bindata/multi_value.rb +144 -0
- data/lib/bindata/registry.rb +13 -8
- data/lib/bindata/rest.rb +41 -0
- data/lib/bindata/sanitize.rb +36 -0
- data/lib/bindata/single.rb +31 -6
- data/lib/bindata/single_value.rb +203 -0
- data/lib/bindata/string.rb +57 -32
- data/lib/bindata/stringz.rb +15 -0
- data/lib/bindata/struct.rb +189 -204
- data/spec/array_spec.rb +66 -42
- data/spec/base_spec.rb +202 -80
- data/spec/choice_spec.rb +172 -51
- data/spec/int_spec.rb +5 -5
- data/spec/lazy_spec.rb +26 -23
- data/spec/multi_value_spec.rb +250 -0
- data/spec/registry_spec.rb +8 -8
- data/spec/rest_spec.rb +30 -0
- data/spec/sanitize_spec.rb +108 -0
- data/spec/single_spec.rb +63 -49
- data/spec/single_value_spec.rb +131 -0
- data/spec/string_spec.rb +47 -47
- data/spec/stringz_spec.rb +29 -29
- data/spec/struct_spec.rb +112 -198
- metadata +58 -57
data/spec/string_spec.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
|
4
4
|
require 'bindata/string'
|
|
5
5
|
|
|
6
|
-
describe "
|
|
6
|
+
describe BinData::String, "with mutually exclusive parameters" do
|
|
7
7
|
it ":value and :initial_value" do
|
|
8
8
|
params = {:value => "", :initial_value => ""}
|
|
9
9
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
|
@@ -20,170 +20,170 @@ describe "Test mutual exclusion of parameters" do
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
describe
|
|
23
|
+
describe BinData::String, "with deprecated parameters" do
|
|
24
24
|
it "should substitude :read_length for :initial_length" do
|
|
25
25
|
obj = BinData::String.new(:initial_length => 3)
|
|
26
26
|
io = StringIO.new("abcdefghij")
|
|
27
27
|
obj.read(io)
|
|
28
|
-
obj.value.should
|
|
28
|
+
obj.value.should == "abc"
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
describe
|
|
32
|
+
describe BinData::String, "with :read_length" do
|
|
33
33
|
before(:each) do
|
|
34
34
|
@str = BinData::String.new(:read_length => 5)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "should have default value" do
|
|
38
|
-
@str.num_bytes.should
|
|
39
|
-
@str.value.should
|
|
38
|
+
@str.num_bytes.should == 0
|
|
39
|
+
@str.value.should == ""
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "should read :read_length bytes" do
|
|
43
43
|
io = StringIO.new("abcdefghij")
|
|
44
44
|
@str.read(io)
|
|
45
|
-
@str.value.should
|
|
45
|
+
@str.value.should == "abcde"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it "should remember :read_length after value is cleared" do
|
|
49
49
|
@str.value = "abc"
|
|
50
|
-
@str.num_bytes.should
|
|
50
|
+
@str.num_bytes.should == 3
|
|
51
51
|
@str.clear
|
|
52
52
|
io = StringIO.new("abcdefghij")
|
|
53
53
|
@str.read(io)
|
|
54
|
-
@str.value.should
|
|
54
|
+
@str.value.should == "abcde"
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
describe
|
|
58
|
+
describe BinData::String, "with :length" do
|
|
59
59
|
before(:each) do
|
|
60
60
|
@str = BinData::String.new(:length => 5)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "should set num_bytes" do
|
|
64
|
-
@str.num_bytes.should
|
|
64
|
+
@str.num_bytes.should == 5
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "should fill value with pad_char" do
|
|
68
|
-
@str.value.should
|
|
68
|
+
@str.value.should == "\0\0\0\0\0"
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it "should retain :length after value is set" do
|
|
72
72
|
@str.value = "abcdefghij"
|
|
73
|
-
@str.num_bytes.should
|
|
73
|
+
@str.num_bytes.should == 5
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
it "should read :length bytes" do
|
|
77
77
|
io = StringIO.new("abcdefghij")
|
|
78
78
|
@str.read(io)
|
|
79
|
-
@str.value.should
|
|
79
|
+
@str.value.should == "abcde"
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it "should pad values less than :length" do
|
|
83
83
|
@str.value = "abc"
|
|
84
|
-
@str.value.should
|
|
84
|
+
@str.value.should == "abc\0\0"
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "should accept values exactly :length" do
|
|
88
88
|
@str.value = "abcde"
|
|
89
|
-
@str.value.should
|
|
89
|
+
@str.value.should == "abcde"
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "should truncate values greater than :length" do
|
|
93
93
|
@str.value = "abcdefg"
|
|
94
|
-
@str.value.should
|
|
94
|
+
@str.value.should == "abcde"
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
describe
|
|
98
|
+
describe BinData::String, "with :read_length and :initial_value" do
|
|
99
99
|
before(:each) do
|
|
100
100
|
@str = BinData::String.new(:read_length => 5, :initial_value => "abcdefghij")
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
it "should use :initial_value before value is read" do
|
|
104
|
-
@str.num_bytes.should
|
|
105
|
-
@str.value.should
|
|
104
|
+
@str.num_bytes.should == 10
|
|
105
|
+
@str.value.should == "abcdefghij"
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
it "should use :read_length for reading" do
|
|
109
109
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
110
110
|
@str.read(io)
|
|
111
|
-
io.pos.should
|
|
111
|
+
io.pos.should == 5
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
it "should forget :initial_value after reading" do
|
|
115
115
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
116
116
|
@str.read(io)
|
|
117
|
-
@str.num_bytes.should
|
|
118
|
-
@str.value.should
|
|
117
|
+
@str.num_bytes.should == 5
|
|
118
|
+
@str.value.should == "ABCDE"
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
describe
|
|
123
|
+
describe BinData::String, "with :read_length and :value" do
|
|
124
124
|
before(:each) do
|
|
125
125
|
@str = BinData::String.new(:read_length => 5, :value => "abcdefghij")
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
it "should not be affected by :read_length before value is read" do
|
|
129
|
-
@str.num_bytes.should
|
|
130
|
-
@str.value.should
|
|
129
|
+
@str.num_bytes.should == 10
|
|
130
|
+
@str.value.should == "abcdefghij"
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
it "should use :read_length for reading" do
|
|
134
134
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
135
135
|
@str.read(io)
|
|
136
|
-
io.pos.should
|
|
136
|
+
io.pos.should == 5
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
it "should not be affected by :read_length after reading" do
|
|
140
140
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
141
141
|
@str.read(io)
|
|
142
|
-
@str.num_bytes.should
|
|
143
|
-
@str.value.should
|
|
142
|
+
@str.num_bytes.should == 10
|
|
143
|
+
@str.value.should == "abcdefghij"
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
it "should return read value before calling done_read" do
|
|
147
147
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
148
148
|
|
|
149
149
|
@str.do_read(io)
|
|
150
|
-
@str.value.should
|
|
150
|
+
@str.value.should == "ABCDE"
|
|
151
151
|
|
|
152
152
|
@str.done_read
|
|
153
|
-
@str.value.should
|
|
153
|
+
@str.value.should == "abcdefghij"
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
describe
|
|
157
|
+
describe BinData::String, "with :length and :initial_value" do
|
|
158
158
|
before(:each) do
|
|
159
159
|
@str = BinData::String.new(:length => 5, :initial_value => "abcdefghij")
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
it "should apply :length to :initial_value" do
|
|
163
|
-
@str.num_bytes.should
|
|
164
|
-
@str.value.should
|
|
163
|
+
@str.num_bytes.should == 5
|
|
164
|
+
@str.value.should == "abcde"
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
it "should forget :initial_value after reading" do
|
|
168
168
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
|
169
169
|
@str.read(io)
|
|
170
|
-
io.pos.should
|
|
171
|
-
@str.num_bytes.should
|
|
172
|
-
@str.value.should
|
|
170
|
+
io.pos.should == 5
|
|
171
|
+
@str.num_bytes.should == 5
|
|
172
|
+
@str.value.should == "ABCDE"
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
-
describe
|
|
176
|
+
describe BinData::String, "with :pad_char" do
|
|
177
177
|
it "should accept a numeric value for :pad_char" do
|
|
178
178
|
@str = BinData::String.new(:length => 5, :pad_char => 6)
|
|
179
179
|
@str.value = "abc"
|
|
180
|
-
@str.value.should
|
|
180
|
+
@str.value.should == "abc\x06\x06"
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
it "should accept a character for :pad_char" do
|
|
184
184
|
@str = BinData::String.new(:length => 5, :pad_char => "R")
|
|
185
185
|
@str.value = "abc"
|
|
186
|
-
@str.value.should
|
|
186
|
+
@str.value.should == "abcRR"
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
it "should not accept a string for :pad_char" do
|
|
@@ -192,37 +192,37 @@ describe "A String with :pad_char" do
|
|
|
192
192
|
end
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
-
describe
|
|
195
|
+
describe BinData::String, "with :trim_value" do
|
|
196
196
|
it "set false is the default" do
|
|
197
197
|
str1 = BinData::String.new(:length => 5)
|
|
198
198
|
str2 = BinData::String.new(:length => 5, :trim_value => false)
|
|
199
199
|
str1.value = "abc"
|
|
200
200
|
str2.value = "abc"
|
|
201
|
-
str1.value.should
|
|
202
|
-
str2.value.should
|
|
201
|
+
str1.value.should == "abc\0\0"
|
|
202
|
+
str2.value.should == "abc\0\0"
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
it "should trim the value" do
|
|
206
206
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
|
207
207
|
str.value = "abcRR"
|
|
208
|
-
str.value.should
|
|
208
|
+
str.value.should == "abc"
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it "should not affect num_bytes" do
|
|
212
212
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
|
213
213
|
str.value = "abcRR"
|
|
214
|
-
str.num_bytes.should
|
|
214
|
+
str.num_bytes.should == 5
|
|
215
215
|
end
|
|
216
216
|
|
|
217
217
|
it "should trim if last char is :pad_char" do
|
|
218
218
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
|
219
219
|
str.value = "abcRR"
|
|
220
|
-
str.value.should
|
|
220
|
+
str.value.should == "abc"
|
|
221
221
|
end
|
|
222
222
|
|
|
223
223
|
it "should not trim if value contains :pad_char not at the end" do
|
|
224
224
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
|
225
225
|
str.value = "abcRRde"
|
|
226
|
-
str.value.should
|
|
226
|
+
str.value.should == "abcRRde"
|
|
227
227
|
end
|
|
228
228
|
end
|
data/spec/stringz_spec.rb
CHANGED
|
@@ -3,50 +3,50 @@
|
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
|
4
4
|
require 'bindata/stringz'
|
|
5
5
|
|
|
6
|
-
describe "
|
|
6
|
+
describe BinData::Stringz, "when empty" do
|
|
7
7
|
before(:each) do
|
|
8
8
|
@str = BinData::Stringz.new
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "should include the zero byte in num_bytes total" do
|
|
12
|
-
@str.num_bytes.should
|
|
12
|
+
@str.num_bytes.should == 1
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "should not append the zero byte terminator to the value" do
|
|
16
|
-
@str.value.should
|
|
16
|
+
@str.value.should == ""
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it "should write the zero byte terminator" do
|
|
20
20
|
io = StringIO.new
|
|
21
21
|
@str.write(io)
|
|
22
22
|
io.rewind
|
|
23
|
-
io.read.should
|
|
23
|
+
io.read.should == "\0"
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
describe
|
|
27
|
+
describe BinData::Stringz, "with value set" do
|
|
28
28
|
before(:each) do
|
|
29
29
|
@str = BinData::Stringz.new
|
|
30
30
|
@str.value = "abcd"
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "should include the zero byte in num_bytes total" do
|
|
34
|
-
@str.num_bytes.should
|
|
34
|
+
@str.num_bytes.should == 5
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "should not append the zero byte terminator to the value" do
|
|
38
|
-
@str.value.should
|
|
38
|
+
@str.value.should == "abcd"
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
it "should write the zero byte terminator" do
|
|
42
42
|
io = StringIO.new
|
|
43
43
|
@str.write(io)
|
|
44
44
|
io.rewind
|
|
45
|
-
io.read.should
|
|
45
|
+
io.read.should == "abcd\0"
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
describe
|
|
49
|
+
describe BinData::Stringz, "when reading" do
|
|
50
50
|
before(:each) do
|
|
51
51
|
@str = BinData::Stringz.new
|
|
52
52
|
end
|
|
@@ -54,15 +54,15 @@ describe "Reading with a Stringz data object" do
|
|
|
54
54
|
it "should stop at the first zero byte" do
|
|
55
55
|
io = StringIO.new("abcd\0xyz\0")
|
|
56
56
|
@str.read(io)
|
|
57
|
-
@str.value.should
|
|
58
|
-
io.read(1).should
|
|
57
|
+
@str.value.should == "abcd"
|
|
58
|
+
io.read(1).should == "x"
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
it "should handle a zero length string" do
|
|
62
62
|
io = StringIO.new("\0abcd")
|
|
63
63
|
@str.read(io)
|
|
64
|
-
@str.value.should
|
|
65
|
-
io.read(1).should
|
|
64
|
+
@str.value.should == ""
|
|
65
|
+
io.read(1).should == "a"
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it "should fail if no zero byte is found" do
|
|
@@ -71,38 +71,38 @@ describe "Reading with a Stringz data object" do
|
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
describe "
|
|
74
|
+
describe BinData::Stringz, " when setting the value" do
|
|
75
75
|
before(:each) do
|
|
76
76
|
@str = BinData::Stringz.new
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
it "should include the zero byte in num_bytes total" do
|
|
80
80
|
@str.value = "abcd"
|
|
81
|
-
@str.num_bytes.should
|
|
81
|
+
@str.num_bytes.should == 5
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
it "should accept empty strings" do
|
|
85
85
|
@str.value = ""
|
|
86
|
-
@str.value.should
|
|
86
|
+
@str.value.should == ""
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
it "should accept strings that aren't zero terminated" do
|
|
90
90
|
@str.value = "abcd"
|
|
91
|
-
@str.value.should
|
|
91
|
+
@str.value.should == "abcd"
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
it "should accept strings that are zero terminated" do
|
|
95
95
|
@str.value = "abcd\0"
|
|
96
|
-
@str.value.should
|
|
96
|
+
@str.value.should == "abcd"
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
it "should accept up to the first zero byte" do
|
|
100
100
|
@str.value = "abcd\0xyz\0"
|
|
101
|
-
@str.value.should
|
|
101
|
+
@str.value.should == "abcd"
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
describe
|
|
105
|
+
describe BinData::Stringz, "with max_length" do
|
|
106
106
|
before(:each) do
|
|
107
107
|
@str = BinData::Stringz.new(:max_length => 5)
|
|
108
108
|
end
|
|
@@ -110,35 +110,35 @@ describe "A Stringz data object with max_length" do
|
|
|
110
110
|
it "should read less than max_length" do
|
|
111
111
|
io = StringIO.new("abc\0xyz")
|
|
112
112
|
@str.read(io)
|
|
113
|
-
@str.value.should
|
|
113
|
+
@str.value.should == "abc"
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
it "should read exactly max_length" do
|
|
117
117
|
io = StringIO.new("abcd\0xyz")
|
|
118
118
|
@str.read(io)
|
|
119
|
-
@str.value.should
|
|
119
|
+
@str.value.should == "abcd"
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "should read no more than max_length" do
|
|
123
123
|
io = StringIO.new("abcdefg\0xyz")
|
|
124
124
|
@str.read(io)
|
|
125
|
-
@str.value.should
|
|
126
|
-
io.read(1).should
|
|
125
|
+
@str.value.should == "abcd"
|
|
126
|
+
io.read(1).should == "f"
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
it "should accept values less than max_length" do
|
|
130
130
|
@str.value = "abc"
|
|
131
|
-
@str.value.should
|
|
131
|
+
@str.value.should == "abc"
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
it "should accept values exactly max_length" do
|
|
135
135
|
@str.value = "abcd"
|
|
136
|
-
@str.value.should
|
|
136
|
+
@str.value.should == "abcd"
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
it "should trim values greater than max_length" do
|
|
140
140
|
@str.value = "abcde"
|
|
141
|
-
@str.value.should
|
|
141
|
+
@str.value.should == "abcd"
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
it "should write values less than max_length" do
|
|
@@ -146,7 +146,7 @@ describe "A Stringz data object with max_length" do
|
|
|
146
146
|
@str.value = "abc"
|
|
147
147
|
@str.write(io)
|
|
148
148
|
io.rewind
|
|
149
|
-
io.read.should
|
|
149
|
+
io.read.should == "abc\0"
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
it "should write values exactly max_length" do
|
|
@@ -154,6 +154,6 @@ describe "A Stringz data object with max_length" do
|
|
|
154
154
|
@str.value = "abcd"
|
|
155
155
|
@str.write(io)
|
|
156
156
|
io.rewind
|
|
157
|
-
io.read.should
|
|
157
|
+
io.read.should == "abcd\0"
|
|
158
158
|
end
|
|
159
159
|
end
|
data/spec/struct_spec.rb
CHANGED
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
|
4
4
|
require 'bindata'
|
|
5
5
|
|
|
6
|
-
describe
|
|
7
|
-
before(:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
describe BinData::Struct, "with hidden fields" do
|
|
7
|
+
before(:each) do
|
|
8
|
+
@params = { :hide => [:b, 'c'],
|
|
9
|
+
:fields => [
|
|
10
|
+
[:int8, :a],
|
|
11
|
+
[:int8, 'b', {:initial_value => 10}],
|
|
12
|
+
[:int8, :c],
|
|
13
|
+
[:int8, :d, {:value => :b}]] }
|
|
14
|
+
@obj = BinData::Struct.new(@params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should not include hidden names in all_possible_field_names" do
|
|
18
|
+
params = BinData::SanitizedParameters.new(BinData::Struct, @params)
|
|
19
|
+
BinData::Struct.all_possible_field_names(params).should == ["a", "d"]
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
it "should only show fields that aren't hidden" do
|
|
@@ -22,9 +24,9 @@ describe "A Struct with hidden fields" do
|
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
it "should be able to access hidden fields directly" do
|
|
25
|
-
@obj.b.should
|
|
27
|
+
@obj.b.should == 10
|
|
26
28
|
@obj.c = 15
|
|
27
|
-
@obj.c.should
|
|
29
|
+
@obj.c.should == 15
|
|
28
30
|
|
|
29
31
|
@obj.should respond_to(:b=)
|
|
30
32
|
end
|
|
@@ -35,187 +37,96 @@ describe "A Struct with hidden fields" do
|
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
describe
|
|
39
|
-
before(:all) do
|
|
40
|
-
eval <<-END
|
|
41
|
-
class DelegateStruct < BinData::Struct
|
|
42
|
-
delegate :b
|
|
43
|
-
int8 :a, :initial_value => :num
|
|
44
|
-
int8 'b', :initial_value => 7
|
|
45
|
-
int8 :c, :value => :b
|
|
46
|
-
end
|
|
47
|
-
END
|
|
48
|
-
@obj = DelegateStruct.new(:num => 5)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "should access custom parameters" do
|
|
52
|
-
@obj.a.should eql(5)
|
|
53
|
-
@obj.b.should eql(7)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should have correct num_bytes" do
|
|
57
|
-
@obj.num_bytes.should eql(3)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "should delegate snapshot" do
|
|
61
|
-
@obj.value = 6
|
|
62
|
-
@obj.snapshot.should eql(6)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "should delegate single_value?" do
|
|
66
|
-
@obj.should be_a_single_value
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "should delegate methods" do
|
|
70
|
-
@obj.should respond_to(:value)
|
|
71
|
-
@obj.value = 9
|
|
72
|
-
@obj.c.should eql(9)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "should identify accepted parameters" do
|
|
76
|
-
@obj.accepted_parameters.should include(:check_value)
|
|
77
|
-
@obj.accepted_parameters.should include(:initial_value)
|
|
78
|
-
@obj.accepted_parameters.should include(:value)
|
|
79
|
-
@obj.accepted_parameters.should_not include(:endian)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it "should pass params when creating" do
|
|
83
|
-
obj = DelegateStruct.new(:initial_value => :val, :val => 14)
|
|
84
|
-
obj.value.should eql(14)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
describe "A Struct with nested delegation" do
|
|
89
|
-
before(:all) do
|
|
90
|
-
eval <<-END
|
|
91
|
-
class DelegateOuterStruct < BinData::Struct
|
|
92
|
-
endian :little
|
|
93
|
-
delegate :b
|
|
94
|
-
int8 :a
|
|
95
|
-
struct :b, :delegate => :y,
|
|
96
|
-
:fields => [[:int8, :x], [:int32, :y], [:int8, :z]]
|
|
97
|
-
end
|
|
98
|
-
END
|
|
99
|
-
@obj = DelegateOuterStruct.new(:initial_value => 7)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "should followed nested delegation" do
|
|
103
|
-
@obj.should be_a_single_value
|
|
104
|
-
@obj.field_names.should eql([])
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it "should forward parameters" do
|
|
108
|
-
@obj.should respond_to(:value)
|
|
109
|
-
@obj.value.should eql(7)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "should identify accepted parameters" do
|
|
113
|
-
@obj.accepted_parameters.should include(:check_value)
|
|
114
|
-
@obj.accepted_parameters.should include(:initial_value)
|
|
115
|
-
@obj.accepted_parameters.should include(:value)
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
describe "Defining a Struct" do
|
|
120
|
-
before(:all) do
|
|
121
|
-
end
|
|
40
|
+
describe BinData::Struct do
|
|
122
41
|
it "should fail on non registered types" do
|
|
42
|
+
params = {:fields => [[:non_registered_type, :a]]}
|
|
123
43
|
lambda {
|
|
124
|
-
|
|
125
|
-
class BadType < BinData::Struct
|
|
126
|
-
non_registerd_type :a
|
|
127
|
-
end
|
|
128
|
-
END
|
|
129
|
-
}.should raise_error(TypeError)
|
|
130
|
-
|
|
131
|
-
lambda {
|
|
132
|
-
BinData::Struct.new(:fields => [[:non_registered_type, :a]])
|
|
44
|
+
BinData::Struct.new(params)
|
|
133
45
|
}.should raise_error(TypeError)
|
|
46
|
+
end
|
|
134
47
|
|
|
48
|
+
it "should fail on all_possible_field_names with unsanitized parameters" do
|
|
49
|
+
params = {:fields => [[:int8, :a], [:int8, :b]]}
|
|
135
50
|
lambda {
|
|
136
|
-
BinData::Struct.
|
|
137
|
-
|
|
138
|
-
}.should raise_error(TypeError)
|
|
51
|
+
BinData::Struct.all_possible_field_names(params)
|
|
52
|
+
}.should raise_error(ArgumentError)
|
|
139
53
|
end
|
|
140
54
|
|
|
141
55
|
it "should fail on duplicate names" do
|
|
56
|
+
params = {:fields => [[:int8, :a], [:int8, :b], [:int8, :a]]}
|
|
142
57
|
lambda {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
int8 :a
|
|
146
|
-
int8 :b
|
|
147
|
-
int8 :a
|
|
148
|
-
end
|
|
149
|
-
END
|
|
150
|
-
}.should raise_error(SyntaxError)
|
|
58
|
+
BinData::Struct.new(params)
|
|
59
|
+
}.should raise_error(NameError)
|
|
151
60
|
end
|
|
152
61
|
|
|
153
|
-
it "should fail on
|
|
62
|
+
it "should fail on duplicate names in nested structs" do
|
|
63
|
+
params = {:fields => [[:int8, :a],
|
|
64
|
+
[:struct, nil, {:fields => [[:int8, :a]]}]]}
|
|
154
65
|
lambda {
|
|
155
|
-
|
|
156
|
-
class ReservedName < BinData::Struct
|
|
157
|
-
int8 :a
|
|
158
|
-
int8 :invert # from Hash.instance_methods
|
|
159
|
-
end
|
|
160
|
-
END
|
|
66
|
+
BinData::Struct.new(params)
|
|
161
67
|
}.should raise_error(NameError)
|
|
68
|
+
end
|
|
162
69
|
|
|
70
|
+
it "should fail on duplicate names in triple nested structs" do
|
|
71
|
+
params = {:fields => [[:int8, :a],
|
|
72
|
+
[:struct, nil, {:fields => [
|
|
73
|
+
[:struct, nil, {:fields => [[:int8, :a]]}]]}]]}
|
|
163
74
|
lambda {
|
|
164
|
-
|
|
165
|
-
BinData::Struct.new(:fields => [[:int8, :a], [:int8, :invert]])
|
|
75
|
+
BinData::Struct.new(params)
|
|
166
76
|
}.should raise_error(NameError)
|
|
167
77
|
end
|
|
168
78
|
|
|
169
|
-
it "should fail on reserved names
|
|
79
|
+
it "should fail on reserved names" do
|
|
80
|
+
# note that #invert is from Hash.instance_methods
|
|
81
|
+
params = {:fields => [[:int8, :a], [:int8, :invert]]}
|
|
170
82
|
lambda {
|
|
171
|
-
|
|
172
|
-
BinData::Struct.new(:delegate => :a,
|
|
173
|
-
:fields => [[:int8, :a], [:int8, :value]])
|
|
83
|
+
BinData::Struct.new(params)
|
|
174
84
|
}.should raise_error(NameError)
|
|
175
85
|
end
|
|
176
86
|
|
|
177
87
|
it "should fail when field name shadows an existing method" do
|
|
88
|
+
# note that #invert is from Hash.instance_methods
|
|
89
|
+
params = {:fields => [[:int8, :object_id]]}
|
|
178
90
|
lambda {
|
|
179
|
-
|
|
180
|
-
class ExistingName < BinData::Struct
|
|
181
|
-
int8 :object_id
|
|
182
|
-
end
|
|
183
|
-
END
|
|
184
|
-
}.should raise_error(NameError)
|
|
185
|
-
|
|
186
|
-
lambda {
|
|
187
|
-
BinData::Struct.new(:fields => [[:int8, :object_id]])
|
|
91
|
+
BinData::Struct.new(params)
|
|
188
92
|
}.should raise_error(NameError)
|
|
189
93
|
end
|
|
190
94
|
|
|
191
95
|
it "should fail on unknown endian" do
|
|
96
|
+
params = {:endian => 'bad value', :fields => []}
|
|
192
97
|
lambda {
|
|
193
|
-
|
|
194
|
-
class BadEndian < BinData::Struct
|
|
195
|
-
endian 'a bad value'
|
|
196
|
-
end
|
|
197
|
-
END
|
|
98
|
+
BinData::Struct.new(params)
|
|
198
99
|
}.should raise_error(ArgumentError)
|
|
199
100
|
end
|
|
200
101
|
end
|
|
201
102
|
|
|
202
|
-
describe
|
|
103
|
+
describe BinData::Struct, "with multiple fields" do
|
|
203
104
|
before(:each) do
|
|
204
|
-
|
|
205
|
-
@obj = BinData::Struct.new(
|
|
105
|
+
@params = { :fields => [ [:int8, :a], [:int8, :b] ] }
|
|
106
|
+
@obj = BinData::Struct.new(@params)
|
|
206
107
|
@obj.a = 1
|
|
207
108
|
@obj.b = 2
|
|
208
109
|
end
|
|
209
110
|
|
|
210
111
|
it "should return num_bytes" do
|
|
211
|
-
@obj.num_bytes(:a).should
|
|
212
|
-
@obj.num_bytes(:b).should
|
|
213
|
-
@obj.num_bytes.should
|
|
112
|
+
@obj.num_bytes(:a).should == 1
|
|
113
|
+
@obj.num_bytes(:b).should == 1
|
|
114
|
+
@obj.num_bytes.should == 2
|
|
214
115
|
end
|
|
215
116
|
|
|
216
117
|
it "should identify accepted parameters" do
|
|
217
|
-
|
|
218
|
-
|
|
118
|
+
BinData::Struct.accepted_parameters.should include(:fields)
|
|
119
|
+
BinData::Struct.accepted_parameters.should include(:hide)
|
|
120
|
+
BinData::Struct.accepted_parameters.should include(:endian)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should return all possible field names" do
|
|
124
|
+
params = BinData::SanitizedParameters.new(BinData::Struct, @params)
|
|
125
|
+
BinData::Struct.all_possible_field_names(params).should == ["a", "b"]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should return field names" do
|
|
129
|
+
@obj.field_names.should == ["a", "b"]
|
|
219
130
|
end
|
|
220
131
|
|
|
221
132
|
it "should clear" do
|
|
@@ -237,21 +148,21 @@ describe "A Struct with multiple fields" do
|
|
|
237
148
|
@obj.write(io)
|
|
238
149
|
|
|
239
150
|
io.rewind
|
|
240
|
-
io.read.should
|
|
151
|
+
io.read.should == "\x01\x02"
|
|
241
152
|
end
|
|
242
153
|
|
|
243
154
|
it "should read ordered" do
|
|
244
155
|
io = StringIO.new "\x03\x04"
|
|
245
156
|
@obj.read(io)
|
|
246
157
|
|
|
247
|
-
@obj.a.should
|
|
248
|
-
@obj.b.should
|
|
158
|
+
@obj.a.should == 3
|
|
159
|
+
@obj.b.should == 4
|
|
249
160
|
end
|
|
250
161
|
|
|
251
162
|
it "should return a snapshot" do
|
|
252
163
|
snap = @obj.snapshot
|
|
253
|
-
snap.a.should
|
|
254
|
-
snap.b.should
|
|
164
|
+
snap.a.should == 1
|
|
165
|
+
snap.b.should == 2
|
|
255
166
|
snap.should == { "a" => 1, "b" => 2 }
|
|
256
167
|
end
|
|
257
168
|
|
|
@@ -264,61 +175,64 @@ describe "A Struct with multiple fields" do
|
|
|
264
175
|
end
|
|
265
176
|
end
|
|
266
177
|
|
|
267
|
-
describe
|
|
268
|
-
before(:
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
int8 :w, :initial_value => 3
|
|
272
|
-
int8 :x, :value => :the_val
|
|
273
|
-
end
|
|
178
|
+
describe BinData::Struct, "with nested structs" do
|
|
179
|
+
before(:each) do
|
|
180
|
+
inner1 = [ [:int8, :w, {:initial_value => 3}],
|
|
181
|
+
[:int8, :x, {:value => :the_val}] ]
|
|
274
182
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
int8 :z
|
|
278
|
-
end
|
|
183
|
+
inner2 = [ [:int8, :y, {:value => lambda { parent.b.w }}],
|
|
184
|
+
[:int8, :z] ]
|
|
279
185
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
END
|
|
286
|
-
@obj = StructOuter.new
|
|
186
|
+
@params = { :fields => [
|
|
187
|
+
[:int8, :a, {:initial_value => 6}],
|
|
188
|
+
[:struct, :b, {:fields => inner1, :the_val => :a}],
|
|
189
|
+
[:struct, nil, {:fields => inner2}]] }
|
|
190
|
+
@obj = BinData::Struct.new(@params)
|
|
287
191
|
end
|
|
288
192
|
|
|
289
193
|
it "should included nested field names" do
|
|
290
194
|
@obj.field_names.should == ["a", "b", "y", "z"]
|
|
291
195
|
end
|
|
292
196
|
|
|
197
|
+
it "should return all possible field names" do
|
|
198
|
+
params = BinData::SanitizedParameters.new(BinData::Struct, @params)
|
|
199
|
+
all_params = BinData::Struct.all_possible_field_names(params)
|
|
200
|
+
all_params.should == ["a", "b", "y", "z"]
|
|
201
|
+
end
|
|
202
|
+
|
|
293
203
|
it "should access nested fields" do
|
|
294
|
-
@obj.a.should
|
|
295
|
-
@obj.b.w.should
|
|
296
|
-
@obj.b.x.should
|
|
297
|
-
@obj.y.should
|
|
204
|
+
@obj.a.should == 6
|
|
205
|
+
@obj.b.w.should == 3
|
|
206
|
+
@obj.b.x.should == 6
|
|
207
|
+
@obj.y.should == 3
|
|
298
208
|
end
|
|
299
209
|
|
|
300
210
|
it "should return correct offset of" do
|
|
301
|
-
@obj.offset_of("b").should
|
|
302
|
-
@obj.offset_of("y").should
|
|
303
|
-
@obj.offset_of("z").should
|
|
211
|
+
@obj.offset_of("b").should == 1
|
|
212
|
+
@obj.offset_of("y").should == 3
|
|
213
|
+
@obj.offset_of("z").should == 4
|
|
304
214
|
end
|
|
305
215
|
end
|
|
306
216
|
|
|
307
|
-
describe
|
|
308
|
-
before(:
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
217
|
+
describe BinData::Struct, "with an endian defined" do
|
|
218
|
+
before(:each) do
|
|
219
|
+
@obj = BinData::Struct.new(:endian => :little,
|
|
220
|
+
:fields => [
|
|
221
|
+
[:uint16, :a],
|
|
222
|
+
[:float, :b],
|
|
223
|
+
[:array, :c,
|
|
224
|
+
{:type => :int8, :initial_length => 2}],
|
|
225
|
+
[:choice, :d,
|
|
226
|
+
{:choices => [[:uint16], [:uint32]],
|
|
227
|
+
:selection => 1}],
|
|
228
|
+
[:struct, :e,
|
|
229
|
+
{:fields => [[:uint16, :f],
|
|
230
|
+
[:uint32be, :g]]}],
|
|
231
|
+
[:struct, :h,
|
|
232
|
+
{:fields => [
|
|
233
|
+
[:struct, :i,
|
|
234
|
+
{:fields => [[:uint16, :j]]}]]}]])
|
|
235
|
+
|
|
322
236
|
end
|
|
323
237
|
|
|
324
238
|
it "should use correct endian" do
|