bindata 1.2.2 → 1.3.1

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.

Files changed (52) hide show
  1. data/ChangeLog +12 -0
  2. data/NEWS +53 -0
  3. data/Rakefile +2 -1
  4. data/examples/NBT.txt +149 -0
  5. data/examples/ip_address.rb +1 -2
  6. data/examples/list.rb +124 -0
  7. data/examples/nbt.rb +195 -0
  8. data/lib/bindata.rb +4 -3
  9. data/lib/bindata/alignment.rb +86 -0
  10. data/lib/bindata/array.rb +21 -29
  11. data/lib/bindata/base.rb +82 -81
  12. data/lib/bindata/base_primitive.rb +66 -48
  13. data/lib/bindata/choice.rb +18 -28
  14. data/lib/bindata/deprecated.rb +17 -0
  15. data/lib/bindata/dsl.rb +25 -15
  16. data/lib/bindata/int.rb +2 -2
  17. data/lib/bindata/io.rb +8 -6
  18. data/lib/bindata/offset.rb +91 -0
  19. data/lib/bindata/primitive.rb +22 -11
  20. data/lib/bindata/record.rb +40 -10
  21. data/lib/bindata/sanitize.rb +15 -30
  22. data/lib/bindata/string.rb +16 -17
  23. data/lib/bindata/stringz.rb +0 -1
  24. data/lib/bindata/struct.rb +17 -6
  25. data/lib/bindata/trace.rb +52 -0
  26. data/lib/bindata/wrapper.rb +28 -6
  27. data/manual.haml +56 -10
  28. data/manual.md +318 -113
  29. data/spec/alignment_spec.rb +61 -0
  30. data/spec/array_spec.rb +139 -178
  31. data/spec/base_primitive_spec.rb +86 -111
  32. data/spec/base_spec.rb +200 -172
  33. data/spec/bits_spec.rb +45 -53
  34. data/spec/choice_spec.rb +91 -87
  35. data/spec/deprecated_spec.rb +36 -14
  36. data/spec/float_spec.rb +16 -68
  37. data/spec/int_spec.rb +26 -27
  38. data/spec/io_spec.rb +105 -105
  39. data/spec/lazy_spec.rb +50 -50
  40. data/spec/primitive_spec.rb +36 -36
  41. data/spec/record_spec.rb +134 -134
  42. data/spec/registry_spec.rb +34 -38
  43. data/spec/rest_spec.rb +8 -11
  44. data/spec/skip_spec.rb +9 -17
  45. data/spec/spec_common.rb +4 -0
  46. data/spec/string_spec.rb +92 -115
  47. data/spec/stringz_spec.rb +41 -74
  48. data/spec/struct_spec.rb +132 -153
  49. data/spec/system_spec.rb +115 -60
  50. data/spec/wrapper_spec.rb +63 -31
  51. data/tasks/pkg.rake +1 -1
  52. metadata +15 -7
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
+ require 'bindata'
5
+
6
+ describe BinData::ResumeByteAlignment do
7
+ class ResumeAlignmentRecord < BinData::Record
8
+ bit4 :a
9
+ resume_byte_alignment
10
+ bit4 :b
11
+ end
12
+
13
+ subject { ResumeAlignmentRecord.new }
14
+
15
+ it "should reset read alignment" do
16
+ subject.read "\x12\x34"
17
+
18
+ subject.a.should == 1
19
+ subject.b.should == 3
20
+ end
21
+
22
+ it "should reset write alignment" do
23
+ subject.assign(:a => 2, :b => 7)
24
+
25
+ subject.to_binary_s.should == "\x20\x70"
26
+ end
27
+ end
28
+
29
+ describe BinData::BitAligned do
30
+ it "should not apply to BinData::Primitives" do
31
+ lambda {
32
+ class BitAlignedPrimitive < BinData::Primitive
33
+ bit_aligned
34
+ end
35
+ }.should raise_error
36
+ end
37
+
38
+ class BitString < BinData::String
39
+ bit_aligned
40
+ end
41
+
42
+ class BitAlignedRecord < BinData::Record
43
+ bit4 :preamble
44
+ bit_string :str, :length => 2
45
+ bit4 :afterward
46
+ end
47
+
48
+ subject { BitAlignedRecord.new }
49
+
50
+ its(:num_bytes) { should == 3 }
51
+
52
+ it "should read" do
53
+ subject.read("\x56\x36\x42")
54
+ subject.should == {"preamble" => 5, "str" => "cd", "afterward" => 2}
55
+ end
56
+
57
+ it "should write" do
58
+ subject.assign(:preamble => 5, :str => "ab", :afterward => 1)
59
+ subject.to_binary_s.should == "\x56\x16\x21"
60
+ end
61
+ end
@@ -25,313 +25,274 @@ describe BinData::Array, "when instantiating" do
25
25
  end
26
26
 
27
27
  describe BinData::Array, "with no elements" do
28
- before(:each) do
29
- @data = BinData::Array.new(:type => :example_single)
30
- end
31
-
32
- it "should be clear" do
33
- @data.should be_clear
34
- end
28
+ subject { BinData::Array.new(:type => :example_single) }
35
29
 
36
- it "should return zero length" do
37
- @data.length.should be_zero
38
- end
39
-
40
- it "should be empty" do
41
- @data.should be_empty
42
- end
30
+ it { should be_clear }
31
+ it { should be_empty }
32
+ its(:length) { should be_zero }
43
33
 
44
34
  it "should return nil for the first element" do
45
- @data.first.should be_nil
35
+ subject.first.should be_nil
46
36
  end
47
37
 
48
38
  it "should return [] for the first n elements" do
49
- @data.first(3).should == []
39
+ subject.first(3).should == []
50
40
  end
51
41
 
52
42
  it "should return nil for the last element" do
53
- @data.last.should be_nil
43
+ subject.last.should be_nil
54
44
  end
55
45
 
56
46
  it "should return [] for the last n elements" do
57
- @data.last(3).should == []
47
+ subject.last(3).should == []
58
48
  end
59
49
  end
60
50
 
61
51
  describe BinData::Array, "with several elements" do
62
- before(:each) do
52
+ subject {
63
53
  type = [:example_single, {:initial_value => lambda { index + 1 }}]
64
- @data = BinData::Array.new(:type => type, :initial_length => 5)
65
- end
54
+ BinData::Array.new(:type => type, :initial_length => 5)
55
+ }
66
56
 
67
- it "should have correct debug name" do
68
- @data[2].debug_name.should == "obj[2]"
69
- end
57
+ it { should be_clear }
58
+ it { should_not be_empty }
59
+ its(:size) { should == 5 }
60
+ its(:length) { should == 5 }
61
+ its(:snapshot) { should == [1, 2, 3, 4, 5] }
62
+ its(:inspect) { should == "[1, 2, 3, 4, 5]" }
70
63
 
71
- it "should have correct offset" do
72
- @data[2].offset.should == ExampleSingle.new.num_bytes * 2
64
+ it "should coerce to ::Array if required" do
65
+ [0].concat(subject).should == [0, 1, 2, 3, 4, 5]
73
66
  end
74
67
 
75
- it "should return a correct snapshot" do
76
- @data.snapshot.should == [1, 2, 3, 4, 5]
68
+ it "should be able to use methods from Enumerable" do
69
+ subject.select { |x| (x % 2) == 0 }.should == [2, 4]
77
70
  end
78
71
 
79
72
  it "should assign primitive values" do
80
- @data.assign([4, 5, 6])
81
- @data.snapshot.should == [4, 5, 6]
73
+ subject.assign([4, 5, 6])
74
+ subject.should == [4, 5, 6]
82
75
  end
83
76
 
84
77
  it "should assign bindata objects" do
85
- o1 = ExampleSingle.new
86
- o1.value = 4
87
- o2 = ExampleSingle.new
88
- o2.value = 5
89
- o3 = ExampleSingle.new
90
- o3.value = 6
91
- @data.assign([o1, o2, o3])
92
- @data.snapshot.should == [4, 5, 6]
78
+ subject.assign([ExampleSingle.new(4), ExampleSingle.new(5), ExampleSingle.new(6)])
79
+ subject.should == [4, 5, 6]
93
80
  end
94
81
 
95
82
  it "should assign bindata array" do
96
83
  array = BinData::Array.new(:type => :example_single)
97
84
  array.push(4, 5, 6)
98
- @data.assign(array)
99
- @data.snapshot.should == [4, 5, 6]
100
- end
101
-
102
- it "should coerce to ::Array if required" do
103
- [0].concat(@data).should == [0, 1, 2, 3, 4, 5]
85
+ subject.assign(array)
86
+ subject.should == [4, 5, 6]
104
87
  end
105
88
 
106
89
  it "should return the first element" do
107
- @data.first.should == 1
90
+ subject.first.should == 1
108
91
  end
109
92
 
110
93
  it "should return the first n elements" do
111
- @data[0...3].should == [1, 2, 3]
112
- @data.first(3).should == [1, 2, 3]
113
- @data.first(99).should == [1, 2, 3, 4, 5]
94
+ subject[0...3].should == [1, 2, 3]
95
+ subject.first(3).should == [1, 2, 3]
96
+ subject.first(99).should == [1, 2, 3, 4, 5]
114
97
  end
115
98
 
116
99
  it "should return the last element" do
117
- @data.last.should == 5
118
- @data[-1].should == 5
100
+ subject.last.should == 5
101
+ subject[-1].should == 5
119
102
  end
120
103
 
121
104
  it "should return the last n elements" do
122
- @data.last(3).should == [3, 4, 5]
123
- @data.last(99).should == [1, 2, 3, 4, 5]
105
+ subject.last(3).should == [3, 4, 5]
106
+ subject.last(99).should == [1, 2, 3, 4, 5]
124
107
 
125
- @data[-3, 100].should == [3, 4, 5]
108
+ subject[-3, 100].should == [3, 4, 5]
126
109
  end
127
110
 
128
- it "should have correct num elements" do
129
- @data.length.should == 5
130
- @data.size.should == 5
111
+ it "should clear" do
112
+ subject[1] = 8
113
+ subject.clear
114
+ subject.should == [1, 2, 3, 4, 5]
131
115
  end
132
116
 
133
- it "should have correct num_bytes" do
134
- @data.num_bytes.should == 5 * ExampleSingle.new.num_bytes
117
+ it "should clear a single element" do
118
+ subject[1] = 8
119
+ subject[1].clear
120
+ subject[1].should == 2
135
121
  end
136
122
 
137
- it "should have correct num_bytes for individual elements" do
138
- @data[0].num_bytes.should == ExampleSingle.new.num_bytes
123
+ it "should be clear if all elements are clear" do
124
+ subject[1] = 8
125
+ subject[1].clear
126
+ subject.should be_clear
139
127
  end
140
128
 
141
- it "should be able to directly access elements" do
142
- @data[1] = 8
143
- @data[1].should == 8
129
+ it "should test clear status of individual elements" do
130
+ subject[1] = 8
131
+ subject[0].should be_clear
132
+ subject[1].should_not be_clear
144
133
  end
145
134
 
146
- it "should not be empty" do
147
- @data.should_not be_empty
135
+ it "should be able to directly access elements" do
136
+ subject[1] = 8
137
+ subject[1].should == 8
148
138
  end
149
139
 
150
- it "should return a nicely formatted array for inspect" do
151
- @data.inspect.should == "[1, 2, 3, 4, 5]"
152
- end
140
+ it "should symmetrically read and write" do
141
+ subject[1] = 8
142
+ str = subject.to_binary_s
153
143
 
154
- it "should be able to use methods from Enumerable" do
155
- @data.select { |x| (x % 2) == 0 }.should == [2, 4]
156
- end
144
+ subject.clear
145
+ subject[1].should == 2
157
146
 
158
- it "should clear" do
159
- @data[1] = 8
160
- @data.clear
161
- @data.should == [1, 2, 3, 4, 5]
147
+ subject.read(str)
148
+ subject[1].should == 8
162
149
  end
163
150
 
164
- it "should clear a single element" do
165
- @data[1] = 8
166
- @data[1].clear
167
- @data[1].should == 2
168
- end
169
-
170
- it "should be clear upon creation" do
171
- @data.should be_clear
151
+ it "should identify index of elements" do
152
+ subject.index(3).should == 2
172
153
  end
173
154
 
174
- it "should be clear if all elements are clear" do
175
- @data[1] = 8
176
- @data[1].clear
177
- @data.should be_clear
155
+ it "should return nil for index of non existent element" do
156
+ subject.index(42).should be_nil
178
157
  end
179
158
 
180
- it "should test clear status of individual elements" do
181
- @data[1] = 8
182
- @data[0].should be_clear
183
- @data[1].should_not be_clear
159
+ it "should have correct debug name" do
160
+ subject[2].debug_name.should == "obj[2]"
184
161
  end
185
162
 
186
- it "should symmetrically read and write" do
187
- @data[1] = 8
188
- str = @data.to_binary_s
189
-
190
- @data.clear
191
- @data[1].should == 2
192
-
193
- @data.read(str)
194
- @data[1].should == 8
163
+ it "should have correct offset" do
164
+ subject[2].offset.should == ExampleSingle.new.num_bytes * 2
195
165
  end
196
166
 
197
- it "should identify index of elements" do
198
- @data.index(3).should == 2
167
+ it "should have correct num_bytes" do
168
+ subject.num_bytes.should == 5 * ExampleSingle.new.num_bytes
199
169
  end
200
170
 
201
- it "should return nil for index of non existent element" do
202
- @data.index(42).should be_nil
171
+ it "should have correct num_bytes for individual elements" do
172
+ subject[0].num_bytes.should == ExampleSingle.new.num_bytes
203
173
  end
204
174
  end
205
175
 
206
176
  describe BinData::Array, "when accessing elements" do
207
- before(:each) do
177
+ subject {
208
178
  type = [:example_single, {:initial_value => lambda { index + 1 }}]
209
- @data = BinData::Array.new(:type => type, :initial_length => 5)
210
- @data[0] = 1
211
- @data[1] = 2
212
- @data[2] = 3
213
- @data[3] = 4
214
- @data[4] = 5
215
- end
179
+ data = BinData::Array.new(:type => type, :initial_length => 5)
180
+ data.assign([1, 2, 3, 4, 5])
181
+ data
182
+ }
216
183
 
217
184
  it "should insert with positive indexes" do
218
- @data.insert(2, 30, 40)
219
- @data.snapshot.should == [1, 2, 30, 40, 3, 4, 5]
185
+ subject.insert(2, 30, 40)
186
+ subject.snapshot.should == [1, 2, 30, 40, 3, 4, 5]
220
187
  end
221
188
 
222
189
  it "should insert with negative indexes" do
223
- @data.insert(-2, 30, 40)
224
- @data.snapshot.should == [1, 2, 3, 4, 30, 40, 5]
190
+ subject.insert(-2, 30, 40)
191
+ subject.snapshot.should == [1, 2, 3, 4, 30, 40, 5]
225
192
  end
226
193
 
227
194
  it "should push" do
228
- @data.push(30, 40)
229
- @data.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
195
+ subject.push(30, 40)
196
+ subject.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
230
197
  end
231
198
 
232
199
  it "should concat" do
233
- @data.concat([30, 40])
234
- @data.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
200
+ subject.concat([30, 40])
201
+ subject.snapshot.should == [1, 2, 3, 4, 5, 30, 40]
235
202
  end
236
203
 
237
204
  it "should unshift" do
238
- @data.unshift(30, 40)
239
- @data.snapshot.should == [30, 40, 1, 2, 3, 4, 5]
205
+ subject.unshift(30, 40)
206
+ subject.snapshot.should == [30, 40, 1, 2, 3, 4, 5]
240
207
  end
241
208
 
242
209
  it "should automatically extend on [index]" do
243
- @data[9].should == 10
244
- @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
210
+ subject[9].should == 10
211
+ subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
245
212
  end
246
213
 
247
214
  it "should automatically extend on []=" do
248
- @data[9] = 30
249
- @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 30]
215
+ subject[9] = 30
216
+ subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 30]
250
217
  end
251
218
 
252
219
  it "should automatically extend on insert" do
253
- @data.insert(7, 30, 40)
254
- @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 30, 40]
220
+ subject.insert(7, 30, 40)
221
+ subject.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 30, 40]
255
222
  end
256
223
 
257
224
  it "should not extend on at" do
258
- @data.at(9).should be_nil
259
- @data.length.should == 5
225
+ subject.at(9).should be_nil
226
+ subject.length.should == 5
260
227
  end
261
228
 
262
229
  it "should not extend on [start, length]" do
263
- @data[9, 2].should be_nil
264
- @data.length.should == 5
230
+ subject[9, 2].should be_nil
231
+ subject.length.should == 5
265
232
  end
266
233
 
267
234
  it "should not extend on [range]" do
268
- @data[9 .. 10].should be_nil
269
- @data.length.should == 5
235
+ subject[9 .. 10].should be_nil
236
+ subject.length.should == 5
270
237
  end
271
238
 
272
239
  it "should raise error on bad input to []" do
273
- lambda { @data["a"] }.should raise_error(TypeError)
274
- lambda { @data[1, "a"] }.should raise_error(TypeError)
240
+ lambda { subject["a"] }.should raise_error(TypeError)
241
+ lambda { subject[1, "a"] }.should raise_error(TypeError)
275
242
  end
276
243
  end
277
244
 
278
- describe BinData::Array, "with :read_until containing +element+" do
279
- before(:each) do
280
- read_until = lambda { element == 5 }
281
- @data = BinData::Array.new(:type => :int8, :read_until => read_until)
282
- end
245
+ describe BinData::Array, "with :read_until" do
283
246
 
284
- it "should read until the sentinel is reached" do
285
- str = "\x01\x02\x03\x04\x05\x06\x07"
286
- @data.read(str)
287
- @data.length.should == 5
288
- end
289
- end
247
+ context "containing +element+" do
248
+ it "should read until the sentinel is reached" do
249
+ read_until = lambda { element == 5 }
250
+ subject = BinData::Array.new(:type => :int8, :read_until => read_until)
290
251
 
291
- describe BinData::Array, "with :read_until containing +array+ and +index+" do
292
- before(:each) do
293
- read_until = lambda { index >= 2 and array[index - 2] == 5 }
294
- @data = BinData::Array.new(:type => :int8, :read_until => read_until)
252
+ subject.read "\x01\x02\x03\x04\x05\x06\x07\x08"
253
+ subject.should == [1, 2, 3, 4, 5]
254
+ end
295
255
  end
296
256
 
297
- it "should read until the sentinel is reached" do
298
- str = "\x01\x02\x03\x04\x05\x06\x07\x08"
299
- @data.read(str)
300
- @data.length.should == 7
301
- end
302
- end
257
+ context "containing +array+ and +index+" do
258
+ it "should read until the sentinel is reached" do
259
+ read_until = lambda { index >= 2 and array[index - 2] == 5 }
260
+ subject = BinData::Array.new(:type => :int8, :read_until => read_until)
303
261
 
304
- describe BinData::Array, "with :read_until => :eof" do
305
- it "should read records until eof" do
306
- obj = BinData::Array.new(:type => :int8, :read_until => :eof)
307
- str = "\x01\x02\x03"
308
- obj.read(str)
309
- obj.snapshot.should == [1, 2, 3]
262
+ subject.read "\x01\x02\x03\x04\x05\x06\x07\x08"
263
+ subject.should == [1, 2, 3, 4, 5, 6, 7]
264
+ end
310
265
  end
311
266
 
312
- it "should read records until eof, ignoring partial records" do
313
- obj = BinData::Array.new(:type => :int16be, :read_until => :eof)
314
- str = "\x00\x01\x00\x02\x03"
315
- obj.read(str)
316
- obj.snapshot.should == [1, 2]
267
+ context "== :eof" do
268
+ it "should read records until eof" do
269
+ subject = BinData::Array.new(:type => :int8, :read_until => :eof)
270
+
271
+ subject.read "\x01\x02\x03"
272
+ subject.should == [1, 2, 3]
273
+ end
274
+
275
+ it "should read records until eof, ignoring partial records" do
276
+ subject = BinData::Array.new(:type => :int16be, :read_until => :eof)
277
+
278
+ subject.read "\x00\x01\x00\x02\x03"
279
+ subject.should == [1, 2]
280
+ end
317
281
  end
318
282
  end
319
283
 
320
284
  describe BinData::Array, "nested within an Array" do
321
- before(:each) do
285
+ subject {
322
286
  nested_array_params = { :type => [:int8, { :initial_value => :index }],
323
287
  :initial_length => lambda { index + 1 } }
324
- @data = BinData::Array.new(:type => [:array, nested_array_params],
325
- :initial_length => 3)
326
- end
288
+ BinData::Array.new(:type => [:array, nested_array_params],
289
+ :initial_length => 3)
290
+ }
327
291
 
328
- it "should use correct index" do
329
- @data.snapshot.should == [ [0], [0, 1], [0, 1, 2] ]
330
- end
292
+ its(:snapshot) { should == [ [0], [0, 1], [0, 1, 2] ] }
331
293
 
332
294
  it "should maintain structure when reading" do
333
- str = "\x04\x05\x06\x07\x08\x09"
334
- @data.read(str)
335
- @data.snapshot.should == [ [4], [5, 6], [7, 8, 9] ]
295
+ subject.read "\x04\x05\x06\x07\x08\x09"
296
+ subject.should == [ [4], [5, 6], [7, 8, 9] ]
336
297
  end
337
298
  end