bindata 0.9.3 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bindata might be problematic. Click here for more details.
- data/ChangeLog +18 -0
- data/NEWS +59 -0
- data/README +22 -23
- data/TODO +18 -12
- data/examples/gzip.rb +4 -4
- data/lib/bindata.rb +4 -3
- data/lib/bindata/array.rb +202 -132
- data/lib/bindata/base.rb +147 -166
- data/lib/bindata/{single.rb → base_primitive.rb} +82 -56
- data/lib/bindata/bits.rb +31 -770
- data/lib/bindata/choice.rb +157 -82
- data/lib/bindata/float.rb +25 -27
- data/lib/bindata/int.rb +144 -177
- data/lib/bindata/io.rb +59 -49
- data/lib/bindata/lazy.rb +80 -50
- data/lib/bindata/params.rb +134 -26
- data/lib/bindata/{single_value.rb → primitive.rb} +71 -64
- data/lib/bindata/{multi_value.rb → record.rb} +52 -70
- data/lib/bindata/registry.rb +49 -17
- data/lib/bindata/rest.rb +6 -10
- data/lib/bindata/sanitize.rb +55 -70
- data/lib/bindata/string.rb +60 -42
- data/lib/bindata/stringz.rb +34 -35
- data/lib/bindata/struct.rb +197 -152
- data/lib/bindata/trace.rb +35 -0
- data/spec/array_spec.rb +128 -112
- data/spec/{single_spec.rb → base_primitive_spec.rb} +102 -61
- data/spec/base_spec.rb +190 -185
- data/spec/bits_spec.rb +126 -98
- data/spec/choice_spec.rb +89 -98
- data/spec/example.rb +19 -0
- data/spec/float_spec.rb +28 -44
- data/spec/int_spec.rb +217 -127
- data/spec/io_spec.rb +41 -24
- data/spec/lazy_spec.rb +95 -49
- data/spec/primitive_spec.rb +191 -0
- data/spec/{multi_value_spec.rb → record_spec.rb} +124 -89
- data/spec/registry_spec.rb +53 -12
- data/spec/rest_spec.rb +2 -3
- data/spec/sanitize_spec.rb +47 -73
- data/spec/spec_common.rb +13 -1
- data/spec/string_spec.rb +34 -23
- data/spec/stringz_spec.rb +10 -18
- data/spec/struct_spec.rb +91 -63
- data/spec/system_spec.rb +291 -0
- metadata +12 -8
- data/spec/single_value_spec.rb +0 -131
data/spec/system_spec.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
+
require File.expand_path(File.dirname(__FILE__)) + '/example'
|
5
|
+
require 'bindata'
|
6
|
+
|
7
|
+
describe "lambdas with index" do
|
8
|
+
before(:all) do
|
9
|
+
eval <<-END
|
10
|
+
class NestedLambdaWithIndex < BinData::Record
|
11
|
+
uint8 :a, :value => lambda { index * 10 }
|
12
|
+
end
|
13
|
+
END
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use index of containing array" do
|
17
|
+
arr = BinData::Array.new(:type =>
|
18
|
+
[:uint8, { :value => lambda { index * 10 } }],
|
19
|
+
:initial_length => 3)
|
20
|
+
arr.snapshot.should == [0, 10, 20]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should use index of nearest containing array" do
|
24
|
+
arr = BinData::Array.new(:type => :nested_lambda_with_index,
|
25
|
+
:initial_length => 3)
|
26
|
+
arr.snapshot.should == [{"a" => 0}, {"a" => 10}, {"a" => 20}]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should fail if there is no containing array" do
|
30
|
+
obj = NestedLambdaWithIndex.new
|
31
|
+
lambda { obj.a.value }.should raise_error(NoMethodError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "lambdas with parent" do
|
36
|
+
it "should access immediate parent when no parent is specified" do
|
37
|
+
class NestedLambdaWithoutParent < BinData::Record
|
38
|
+
int8 :a, :value => 5
|
39
|
+
int8 :b, :value => lambda { a }
|
40
|
+
end
|
41
|
+
|
42
|
+
class TestLambdaWithoutParent < BinData::Record
|
43
|
+
int8 :a, :value => 3
|
44
|
+
nested_lambda_without_parent :x
|
45
|
+
end
|
46
|
+
|
47
|
+
obj = TestLambdaWithoutParent.new
|
48
|
+
obj.x.b.should == 5
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should access parent's parent when parent is specified" do
|
52
|
+
class NestedLambdaWithParent < BinData::Record
|
53
|
+
int8 :a, :value => 5
|
54
|
+
int8 :b, :value => lambda { parent.a }
|
55
|
+
end
|
56
|
+
|
57
|
+
class TestLambdaWithParent < BinData::Record
|
58
|
+
int8 :a, :value => 3
|
59
|
+
nested_lambda_with_parent :x
|
60
|
+
end
|
61
|
+
|
62
|
+
obj = TestLambdaWithParent.new
|
63
|
+
obj.x.b.should == 3
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "Records with choice field" do
|
68
|
+
before(:all) do
|
69
|
+
eval <<-END
|
70
|
+
class TupleRecord < BinData::Record
|
71
|
+
uint8 :a, :value => 3
|
72
|
+
uint8 :b, :value => 5
|
73
|
+
end
|
74
|
+
|
75
|
+
class RecordWithChoiceField < BinData::Record
|
76
|
+
choice :x, :choices => [[:tuple_record]], :selection => 0
|
77
|
+
end
|
78
|
+
|
79
|
+
class RecordWithNestedChoiceField < BinData::Record
|
80
|
+
choice :x, :choices => [
|
81
|
+
[:choice, {
|
82
|
+
:choices => [[:tuple_record]],
|
83
|
+
:selection => 0}
|
84
|
+
]
|
85
|
+
],
|
86
|
+
:selection => 0
|
87
|
+
end
|
88
|
+
END
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should treat choice object transparently " do
|
92
|
+
obj = RecordWithChoiceField.new
|
93
|
+
|
94
|
+
obj.x.a.should == 3
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should treat nested choice object transparently " do
|
98
|
+
obj = RecordWithNestedChoiceField.new
|
99
|
+
|
100
|
+
obj.x.a.should == 3
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have correct offset" do
|
104
|
+
obj = RecordWithNestedChoiceField.new
|
105
|
+
obj.x.b.offset.should == 1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe BinData::Array, "of bits" do
|
110
|
+
before(:each) do
|
111
|
+
@data = BinData::Array.new(:type => :bit1, :initial_length => 15)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should read" do
|
115
|
+
str = [0b0001_0100, 0b1000_1000].pack("CC")
|
116
|
+
@data.read(str)
|
117
|
+
@data[0].should == 0
|
118
|
+
@data[1].should == 0
|
119
|
+
@data[2].should == 0
|
120
|
+
@data[3].should == 1
|
121
|
+
@data[4].should == 0
|
122
|
+
@data[5].should == 1
|
123
|
+
@data[6].should == 0
|
124
|
+
@data[7].should == 0
|
125
|
+
@data[8].should == 1
|
126
|
+
@data[9].should == 0
|
127
|
+
@data[10].should == 0
|
128
|
+
@data[11].should == 0
|
129
|
+
@data[12].should == 1
|
130
|
+
@data[13].should == 0
|
131
|
+
@data[14].should == 0
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should write" do
|
135
|
+
@data[3] = 1
|
136
|
+
@data.to_binary_s.should == [0b0001_0000, 0b0000_0000].pack("CC")
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should return num_bytes" do
|
140
|
+
@data.num_bytes.should == 2
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should have correct offset" do
|
144
|
+
@data[7].offset.should == 0
|
145
|
+
@data[8].offset.should == 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "Objects with debug_name" do
|
150
|
+
it "should have default name of obj" do
|
151
|
+
el = ExampleSingle.new
|
152
|
+
el.debug_name.should == "obj"
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should include array index" do
|
156
|
+
arr = BinData::Array.new(:type => :example_single, :initial_length => 2)
|
157
|
+
arr[2].debug_name.should == "obj[2]"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should include field name" do
|
161
|
+
s = BinData::Struct.new(:fields => [[:example_single, :a]])
|
162
|
+
s.a.debug_name.should == "obj.a"
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should delegate to choice" do
|
166
|
+
choice_params = {:choices => [:example_single], :selection => 0}
|
167
|
+
s = BinData::Struct.new(:fields => [[:choice, :a, choice_params]])
|
168
|
+
s.a.debug_name.should == "obj.a"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should nest" do
|
172
|
+
nested_struct_params = {:fields => [[:example_single, :c]]}
|
173
|
+
struct_params = {:fields => [[:struct, :b, nested_struct_params]]}
|
174
|
+
s = BinData::Struct.new(:fields => [[:struct, :a, struct_params]])
|
175
|
+
s.a.b.c.debug_name.should == "obj.a.b.c"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "Tracing" do
|
180
|
+
it "should trace arrays" do
|
181
|
+
arr = BinData::Array.new(:type => :int8, :initial_length => 5)
|
182
|
+
|
183
|
+
io = StringIO.new
|
184
|
+
BinData::trace_reading(io) { arr.read("\x01\x02\x03\x04\x05") }
|
185
|
+
io.rewind
|
186
|
+
|
187
|
+
expected = (0..4).collect { |i| "obj[#{i}] => #{i + 1}\n" }.join("")
|
188
|
+
io.read.should == expected
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should trace custom single values" do
|
192
|
+
class DebugNamePrimitive < BinData::Primitive
|
193
|
+
int8 :ex
|
194
|
+
def get; self.ex; end
|
195
|
+
def set(val) self.ex = val; end
|
196
|
+
end
|
197
|
+
|
198
|
+
obj = DebugNamePrimitive.new
|
199
|
+
|
200
|
+
io = StringIO.new
|
201
|
+
BinData::trace_reading(io) { obj.read("\x01") }
|
202
|
+
io.rewind
|
203
|
+
|
204
|
+
io.read.should == ["obj-internal-.ex => 1\n", "obj => 1\n"].join("")
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should trace choice selection" do
|
208
|
+
obj = BinData::Choice.new(:choices => [:int8, :int16be], :selection => 0)
|
209
|
+
|
210
|
+
io = StringIO.new
|
211
|
+
BinData::trace_reading(io) { obj.read("\x01") }
|
212
|
+
io.rewind
|
213
|
+
|
214
|
+
io.read.should == ["obj-selection- => 0\n", "obj => 1\n"].join("")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "Forward referencing with Single" do
|
219
|
+
before(:all) do
|
220
|
+
eval <<-END
|
221
|
+
class FRSingle < BinData::Record
|
222
|
+
uint8 :len, :value => lambda { data.length }
|
223
|
+
string :data, :read_length => :len
|
224
|
+
end
|
225
|
+
END
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should initialise" do
|
229
|
+
@obj = FRSingle.new
|
230
|
+
@obj.snapshot.should == {"len" => 0, "data" => ""}
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should read" do
|
234
|
+
@obj = FRSingle.new
|
235
|
+
@obj.read("\x04test")
|
236
|
+
@obj.snapshot.should == {"len" => 4, "data" => "test"}
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should set value" do
|
240
|
+
@obj = FRSingle.new
|
241
|
+
@obj.data = "hello"
|
242
|
+
@obj.snapshot.should == {"len" => 5, "data" => "hello"}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "Forward referencing with Array" do
|
247
|
+
before(:all) do
|
248
|
+
eval <<-END
|
249
|
+
class FRArray < BinData::Record
|
250
|
+
uint8 :len, :value => lambda { data.length }
|
251
|
+
array :data, :type => :uint8, :initial_length => :len
|
252
|
+
end
|
253
|
+
END
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should initialise" do
|
257
|
+
@obj = FRArray.new
|
258
|
+
@obj.snapshot.should == {"len" => 0, "data" => []}
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should read" do
|
262
|
+
@obj = FRArray.new
|
263
|
+
@obj.read("\x04\x01\x02\x03\x04")
|
264
|
+
@obj.snapshot.should == {"len" => 4, "data" => [1, 2, 3, 4]}
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should set value" do
|
268
|
+
@obj = FRArray.new
|
269
|
+
@obj.data = [1, 2, 3]
|
270
|
+
@obj.snapshot.should == {"len" => 3, "data" => [1, 2, 3]}
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "Evaluating custom parameters" do
|
275
|
+
before(:all) do
|
276
|
+
eval <<-END
|
277
|
+
class CustomParameterRecord < BinData::Record
|
278
|
+
mandatory_parameter :zz
|
279
|
+
|
280
|
+
uint8 :a, :value => :zz
|
281
|
+
uint8 :b, :value => :a
|
282
|
+
uint8 :c, :custom => :b
|
283
|
+
end
|
284
|
+
END
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should recursively evaluate parameter" do
|
288
|
+
obj = CustomParameterRecord.new(:zz => 5)
|
289
|
+
obj.c.eval_parameter(:custom).should == 5
|
290
|
+
end
|
291
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bindata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dion Mendel
|
@@ -9,7 +9,7 @@ autorequire: bindata
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-04-17 00:00:00 +08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -26,38 +26,42 @@ files:
|
|
26
26
|
- INSTALL
|
27
27
|
- README
|
28
28
|
- GPL
|
29
|
+
- NEWS
|
29
30
|
- TODO
|
30
31
|
- COPYING
|
31
32
|
- examples/gzip.rb
|
32
33
|
- spec/float_spec.rb
|
33
|
-
- spec/single_value_spec.rb
|
34
34
|
- spec/base_spec.rb
|
35
35
|
- spec/sanitize_spec.rb
|
36
36
|
- spec/lazy_spec.rb
|
37
37
|
- spec/io_spec.rb
|
38
38
|
- spec/choice_spec.rb
|
39
|
+
- spec/base_primitive_spec.rb
|
39
40
|
- spec/array_spec.rb
|
40
41
|
- spec/stringz_spec.rb
|
41
|
-
- spec/
|
42
|
+
- spec/primitive_spec.rb
|
43
|
+
- spec/example.rb
|
44
|
+
- spec/system_spec.rb
|
42
45
|
- spec/int_spec.rb
|
43
46
|
- spec/string_spec.rb
|
44
47
|
- spec/struct_spec.rb
|
45
48
|
- spec/spec_common.rb
|
46
|
-
- spec/single_spec.rb
|
47
49
|
- spec/bits_spec.rb
|
48
50
|
- spec/registry_spec.rb
|
49
51
|
- spec/rest_spec.rb
|
52
|
+
- spec/record_spec.rb
|
50
53
|
- lib/bindata
|
51
54
|
- lib/bindata/params.rb
|
52
|
-
- lib/bindata/single.rb
|
53
55
|
- lib/bindata/int.rb
|
54
56
|
- lib/bindata/choice.rb
|
57
|
+
- lib/bindata/trace.rb
|
55
58
|
- lib/bindata/registry.rb
|
56
|
-
- lib/bindata/
|
59
|
+
- lib/bindata/base_primitive.rb
|
57
60
|
- lib/bindata/struct.rb
|
58
61
|
- lib/bindata/stringz.rb
|
59
|
-
- lib/bindata/multi_value.rb
|
60
62
|
- lib/bindata/bits.rb
|
63
|
+
- lib/bindata/record.rb
|
64
|
+
- lib/bindata/primitive.rb
|
61
65
|
- lib/bindata/rest.rb
|
62
66
|
- lib/bindata/base.rb
|
63
67
|
- lib/bindata/array.rb
|
data/spec/single_value_spec.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
|
-
require 'bindata'
|
5
|
-
|
6
|
-
describe BinData::SingleValue do
|
7
|
-
before(:all) do
|
8
|
-
eval <<-END
|
9
|
-
class SingleValueWithEndian < BinData::SingleValue
|
10
|
-
endian :little
|
11
|
-
int16 :a
|
12
|
-
def get; self.a; end
|
13
|
-
def set(v); self.a = v; end
|
14
|
-
end
|
15
|
-
END
|
16
|
-
end
|
17
|
-
|
18
|
-
before(:each) do
|
19
|
-
@obj = SingleValueWithEndian.new
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should support endian" do
|
23
|
-
@obj.value = 5
|
24
|
-
@obj.to_s.should == "\x05\x00"
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should set value" do
|
28
|
-
@obj.value = 5
|
29
|
-
@obj.to_s.should == "\x05\x00"
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should read value" do
|
33
|
-
@obj.read("\x00\x01")
|
34
|
-
@obj.value.should == 0x100
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should accept standard parameters" do
|
38
|
-
obj = SingleValueWithEndian.new(:initial_value => 2)
|
39
|
-
obj.to_s.should == "\x02\x00"
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should return num_bytes" do
|
43
|
-
@obj.num_bytes.should == 2
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should raise error on missing methods" do
|
47
|
-
lambda {
|
48
|
-
@obj.does_not_exist
|
49
|
-
}.should raise_error(NoMethodError)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe BinData::SingleValue, "requiring extra parameters" do
|
54
|
-
before(:all) do
|
55
|
-
eval <<-END
|
56
|
-
class SingleValueWithExtra < BinData::SingleValue
|
57
|
-
int8 :a, :initial_value => :iv
|
58
|
-
def get; self.a; end
|
59
|
-
def set(v); self.a = v; end
|
60
|
-
end
|
61
|
-
END
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should pass parameters correctly" do
|
65
|
-
obj = SingleValueWithExtra.new(:iv => 5)
|
66
|
-
obj.value.should == 5
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe BinData::SingleValue, "when subclassing" do
|
71
|
-
before(:all) do
|
72
|
-
eval <<-END
|
73
|
-
class SubClassOfSingleValue < BinData::SingleValue
|
74
|
-
public :get, :set
|
75
|
-
end
|
76
|
-
END
|
77
|
-
end
|
78
|
-
|
79
|
-
before(:each) do
|
80
|
-
@obj = SubClassOfSingleValue.new
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should raise errors on unimplemented methods" do
|
84
|
-
lambda { @obj.set(nil) }.should raise_error(NotImplementedError)
|
85
|
-
lambda { @obj.get }.should raise_error(NotImplementedError)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe BinData::SingleValue, "when defining" do
|
90
|
-
it "should fail on non registered types" do
|
91
|
-
lambda {
|
92
|
-
eval <<-END
|
93
|
-
class BadTypeSingleValue < BinData::SingleValue
|
94
|
-
non_registerd_type :a
|
95
|
-
end
|
96
|
-
END
|
97
|
-
}.should raise_error(TypeError)
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should fail on duplicate names" do
|
101
|
-
lambda {
|
102
|
-
eval <<-END
|
103
|
-
class DuplicateNameSingleValue < BinData::SingleValue
|
104
|
-
int8 :a
|
105
|
-
int8 :b
|
106
|
-
int8 :a
|
107
|
-
end
|
108
|
-
END
|
109
|
-
}.should raise_error(SyntaxError)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should fail when field name shadows an existing method" do
|
113
|
-
lambda {
|
114
|
-
eval <<-END
|
115
|
-
class ExistingNameSingleValue < BinData::SingleValue
|
116
|
-
int8 :object_id
|
117
|
-
end
|
118
|
-
END
|
119
|
-
}.should raise_error(NameError)
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should fail on unknown endian" do
|
123
|
-
lambda {
|
124
|
-
eval <<-END
|
125
|
-
class BadEndianSingleValue < BinData::SingleValue
|
126
|
-
endian 'a bad value'
|
127
|
-
end
|
128
|
-
END
|
129
|
-
}.should raise_error(ArgumentError)
|
130
|
-
end
|
131
|
-
end
|