bindata 2.0.0 → 2.1.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.

@@ -1,3 +1,3 @@
1
1
  module BinData
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -3,12 +3,12 @@ module BinData
3
3
 
4
4
  # Don't override initialize. If you are defining a new kind of datatype
5
5
  # (list, array, choice etc) then put your initialization code in
6
- # #initialize_instance. This is because BinData objects can be initialized
7
- # as prototypes and your initialization code may not be called.
6
+ # #initialize_instance. BinData objects might be initialized as prototypes
7
+ # and your initialization code may not be called.
8
8
  #
9
9
  # If you're subclassing BinData::Record, you are definitely doing the wrong
10
10
  # thing. Read the documentation on how to use BinData.
11
- # http://bindata.rubyforge.org/manual.html#records
11
+ # http://github.com/dmendel/bindata/wiki/Records
12
12
  alias_method :initialize_without_warning, :initialize
13
13
  def initialize_with_warning(*args)
14
14
  owner = method(:initialize).owner
@@ -29,5 +29,11 @@ module BinData
29
29
  end
30
30
  end
31
31
 
32
+ # #offset has been renamed to #abs_offset.
33
+ # Eventually #rel_offset will be renamed to #offset.
34
+ def offset
35
+ warn "#offset is deprecated in #{debug_name}. Use #abs_offset instead"
36
+ abs_offset
37
+ end
32
38
  end
33
39
  end
@@ -168,7 +168,7 @@ describe BinData::Array, "with several elements" do
168
168
  end
169
169
 
170
170
  it "has correct offset" do
171
- obj[2].offset.must_equal ExampleSingle.new.num_bytes * 2
171
+ obj[2].rel_offset.must_equal ExampleSingle.new.num_bytes * 2
172
172
  end
173
173
 
174
174
  it "has correct num_bytes" do
@@ -364,8 +364,8 @@ describe BinData::Array, "of bits" do
364
364
  end
365
365
 
366
366
  it "has correct offset" do
367
- obj[7].offset.must_equal 0
368
- obj[8].offset.must_equal 1
367
+ obj[7].rel_offset.must_equal 0
368
+ obj[8].rel_offset.must_equal 1
369
369
  end
370
370
  end
371
371
 
@@ -170,40 +170,6 @@ describe BinData::BasePrimitive, "with :value" do
170
170
  end
171
171
  end
172
172
 
173
- describe BinData::BasePrimitive, "checking read value" do
174
- let(:io) { ExampleSingle.io_with_value(12) }
175
-
176
- describe ":check_value is non boolean" do
177
- it "succeeds when check_value is correct" do
178
- skip "deprecated"
179
- data = ExampleSingle.new(:check_value => 12)
180
- data.read(io)
181
- data.value.must_equal 12
182
- end
183
-
184
- it "fails when check_value is incorrect" do
185
- skip "deprecated"
186
- data = ExampleSingle.new(:check_value => lambda { 99 })
187
- lambda { data.read(io) }.must_raise BinData::ValidityError
188
- end
189
- end
190
-
191
- describe ":check_value is boolean" do
192
- it "succeeds when check_value is true" do
193
- skip "deprecated"
194
- data = ExampleSingle.new(:check_value => lambda { value < 20 })
195
- data.read(io)
196
- data.value.must_equal 12
197
- end
198
-
199
- it "fails when check_value is false" do
200
- skip "deprecated"
201
- data = ExampleSingle.new(:check_value => lambda { value > 20 })
202
- lambda { data.read(io) }.must_raise BinData::ValidityError
203
- end
204
- end
205
- end
206
-
207
173
  describe BinData::BasePrimitive, "asserting value" do
208
174
  let(:io) { ExampleSingle.io_with_value(12) }
209
175
 
@@ -5,66 +5,58 @@ require File.expand_path(File.join(File.dirname(__FILE__), "common"))
5
5
  module AllBitfields
6
6
 
7
7
  def test_has_a_sensible_value_of_zero
8
- all_classes do |bit_class|
9
- bit_class.new.must_equal 0
8
+ all_objects do |obj, nbits|
9
+ obj.must_equal 0
10
10
  end
11
11
  end
12
12
 
13
13
  def test_avoids_underflow
14
- all_classes do |bit_class|
15
- obj = bit_class.new
16
-
14
+ all_objects do |obj, nbits|
17
15
  obj.assign(min_value - 1)
18
16
  obj.must_equal min_value
19
17
  end
20
18
  end
21
19
 
22
20
  def test_avoids_overflow
23
- all_classes do |bit_class|
24
- obj = bit_class.new
25
-
21
+ all_objects do |obj, nbits|
26
22
  obj.assign(max_value + 1)
27
23
  obj.must_equal max_value
28
24
  end
29
25
  end
30
26
 
31
27
  def test_assign_values
32
- all_classes do |bit_class|
28
+ all_objects do |obj, nbits|
33
29
  some_values_within_range.each do |val|
34
- obj = bit_class.new
35
30
  obj.assign(val)
36
-
37
31
  obj.must_equal val
38
32
  end
39
33
  end
40
34
  end
41
35
 
42
36
  def test_assign_values_from_other_bit_objects
43
- all_classes do |bit_class|
37
+ all_objects do |obj, nbits|
44
38
  some_values_within_range.each do |val|
45
- obj = bit_class.new
46
- obj.assign(bit_class.new(val))
47
-
39
+ obj.assign(obj.new(val))
48
40
  obj.must_equal val
49
41
  end
50
42
  end
51
43
  end
52
44
 
53
45
  def test_symmetrically_read_and_write
54
- all_classes do |bit_class|
46
+ all_objects do |obj, nbits|
55
47
  some_values_within_range.each do |val|
56
- obj = bit_class.new
57
48
  obj.assign(val)
58
-
59
- obj.value_read_from_written.must_equal obj
49
+ other = obj.new
50
+ other.read(obj.to_binary_s)
51
+ other.must_equal obj
60
52
  end
61
53
  end
62
54
  end
63
55
 
64
- def all_classes(&block)
65
- @bits.each_pair do |bit_class, nbits|
56
+ def all_objects(&block)
57
+ @bits.each do |obj, nbits|
66
58
  @nbits = nbits
67
- yield bit_class
59
+ yield obj, nbits
68
60
  end
69
61
  end
70
62
 
@@ -98,7 +90,7 @@ module AllBitfields
98
90
  end
99
91
 
100
92
  def generate_bit_classes_to_test(endian, signed)
101
- bits = {}
93
+ bits = []
102
94
  if signed
103
95
  base = "Sbit"
104
96
  start = 2
@@ -107,12 +99,20 @@ def generate_bit_classes_to_test(endian, signed)
107
99
  start = 1
108
100
  end
109
101
 
110
- (start .. 50).each do |nbits|
102
+ (start .. 64).each do |nbits|
111
103
  name = "#{base}#{nbits}"
112
104
  name << "le" if endian == :little
113
- bit_class = BinData.const_get(name)
114
- bits[bit_class] = nbits
105
+ obj = BinData.const_get(name).new
106
+ bits << [obj, nbits]
107
+ end
108
+
109
+ (start .. 64).each do |nbits|
110
+ name = "#{base}"
111
+ name << "Le" if endian == :little
112
+ obj = BinData.const_get(name).new(:nbits => nbits)
113
+ bits << [obj, nbits]
115
114
  end
115
+
116
116
  bits
117
117
  end
118
118
 
@@ -125,11 +125,12 @@ describe "Unsigned big endian bitfields" do
125
125
  end
126
126
 
127
127
  it "read big endian values" do
128
- @bits.each_pair do |bit_class, nbits|
128
+ all_objects do |obj, nbits|
129
129
  nbytes = (nbits + 7) / 8
130
130
  str = [0b1000_0000].pack("C") + "\000" * (nbytes - 1)
131
131
 
132
- bit_class.read(str).must_equal 1 << (nbits - 1)
132
+ obj.read(str)
133
+ obj.must_equal 1 << (nbits - 1)
133
134
  end
134
135
  end
135
136
  end
@@ -143,11 +144,12 @@ describe "Signed big endian bitfields" do
143
144
  end
144
145
 
145
146
  it "read big endian values" do
146
- @bits.each_pair do |bit_class, nbits|
147
+ all_objects do |obj, nbits|
147
148
  nbytes = (nbits + 7) / 8
148
149
  str = [0b0100_0000].pack("C") + "\000" * (nbytes - 1)
149
150
 
150
- bit_class.read(str).must_equal 1 << (nbits - 2)
151
+ obj.read(str)
152
+ obj.must_equal 1 << (nbits - 2)
151
153
  end
152
154
  end
153
155
  end
@@ -161,11 +163,12 @@ describe "Unsigned little endian bitfields" do
161
163
  end
162
164
 
163
165
  it "read little endian values" do
164
- @bits.each_pair do |bit_class, nbits|
166
+ all_objects do |obj, nbits|
165
167
  nbytes = (nbits + 7) / 8
166
168
  str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
167
169
 
168
- bit_class.read(str).must_equal 1
170
+ obj.read(str)
171
+ obj.must_equal 1
169
172
  end
170
173
  end
171
174
  end
@@ -179,11 +182,12 @@ describe "Signed little endian bitfields" do
179
182
  end
180
183
 
181
184
  it "read little endian values" do
182
- @bits.each_pair do |bit_class, nbits|
185
+ all_objects do |obj, nbits|
183
186
  nbytes = (nbits + 7) / 8
184
187
  str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
185
188
 
186
- bit_class.read(str).must_equal 1
189
+ obj.read(str)
190
+ obj.must_equal 1
187
191
  end
188
192
  end
189
193
  end
@@ -1,4 +1,8 @@
1
1
  require 'rubygems'
2
+
3
+ require 'coveralls'
4
+ Coveralls.wear!
5
+
2
6
  require 'minitest/autorun'
3
7
  require 'stringio'
4
8
 
@@ -152,6 +152,21 @@ describe BinData::IO::Write, "when writing" do
152
152
  stream.value.must_equal "abcd"
153
153
  end
154
154
 
155
+ it "has #offset" do
156
+ io.offset.must_equal 0
157
+
158
+ io.writebytes("abcd")
159
+ io.offset.must_equal 4
160
+
161
+ io.writebytes("ABCD")
162
+ io.offset.must_equal 8
163
+ end
164
+
165
+ it "rounds up #offset when writing bits" do
166
+ io.writebits(123, 9, :little)
167
+ io.offset.must_equal 2
168
+ end
169
+
155
170
  it "flushes" do
156
171
  io.writebytes("abcd")
157
172
  io.flush
@@ -73,12 +73,16 @@ end
73
73
 
74
74
  describe BinData::LazyEvaluator, "with one parent" do
75
75
  subject {
76
- parent_methods = {:m1 => 'Pm1', :com1 => 'PmC', :mm => 3}
76
+ parent_methods = {:m1 => 'Pm1', :m2 => 'Pm2', :com1 => 'PmC', :mm => 3}
77
77
  parent_params = {:p1 => 'Pp1', :com1 => 'PpC'}
78
78
  parent_obj = MockBinDataObject.new(parent_methods, parent_params)
79
79
 
80
- def parent_obj.echo(a1, a2)
81
- [a1, a2]
80
+ class << parent_obj
81
+ def echo(a1, a2)
82
+ [a1, a2]
83
+ end
84
+
85
+ private :m2
82
86
  end
83
87
 
84
88
  methods = {:m1 => 'm1', :com1 => 'mC'}
@@ -118,6 +122,10 @@ describe BinData::LazyEvaluator, "with one parent" do
118
122
  lazy_eval(lambda { echo(p1, m1) }).must_equal ['Pp1', 'Pm1']
119
123
  end
120
124
 
125
+ it "invokes private methods in the parent" do
126
+ lazy_eval(lambda { m2 }).must_equal 'Pm2'
127
+ end
128
+
121
129
  it "resolves parameters in preference to methods in the parent" do
122
130
  lazy_eval(lambda { com1 }).must_equal 'PpC'
123
131
  end
@@ -241,12 +241,12 @@ describe BinData::Record, "with nested structs" do
241
241
  obj.c.y.must_equal 3
242
242
  end
243
243
 
244
- it "returns correct offset" do
245
- obj.offset.must_equal 0
246
- obj.b.offset.must_equal 1
247
- obj.b.w.offset.must_equal 1
248
- obj.c.offset.must_equal 3
249
- obj.c.z.offset.must_equal 4
244
+ it "returns correct abs_offset" do
245
+ obj.abs_offset.must_equal 0
246
+ obj.b.abs_offset.must_equal 1
247
+ obj.b.w.abs_offset.must_equal 1
248
+ obj.c.abs_offset.must_equal 3
249
+ obj.c.z.abs_offset.must_equal 4
250
250
  end
251
251
 
252
252
  it "returns correct rel_offset" do
@@ -378,6 +378,77 @@ describe BinData::Record, "with an endian defined" do
378
378
  end
379
379
  end
380
380
 
381
+ describe BinData::Record, "with endian :big_and_little" do
382
+ class RecordWithBnLEndian < BinData::Record
383
+ endian :big_and_little
384
+ int16 :a, :value => 1
385
+ end
386
+
387
+ it "is not registered" do
388
+ lambda {
389
+ BinData::RegisteredClasses.lookup("RecordWithBnLEndian")
390
+ }.must_raise BinData::UnRegisteredTypeError
391
+ end
392
+
393
+ it "creates big endian version" do
394
+ obj = RecordWithBnLEndianBe.new
395
+ obj.to_binary_s.must_equal binary("\x00\x01")
396
+ end
397
+
398
+ it "creates little endian version" do
399
+ obj = RecordWithBnLEndianLe.new
400
+ obj.to_binary_s.must_equal binary("\x01\x00")
401
+ end
402
+
403
+ it "requires :endian as argument" do
404
+ lambda {
405
+ RecordWithBnLEndian.new
406
+ }.must_raise ArgumentError
407
+ end
408
+
409
+ it "accepts :endian as argument" do
410
+ obj = RecordWithBnLEndian.new(:endian => :little)
411
+ obj.to_binary_s.must_equal binary("\x01\x00")
412
+ end
413
+ end
414
+
415
+ describe BinData::Record, "with endian :big_and_little when subclassed" do
416
+ class ARecordWithBnLEndian < BinData::Record
417
+ endian :big_and_little
418
+ int16 :a, :value => 1
419
+ end
420
+ class BRecordWithBnLEndian < ARecordWithBnLEndian
421
+ int16 :b, :value => 2
422
+ end
423
+
424
+ it "is not registered" do
425
+ lambda {
426
+ BinData::RegisteredClasses.lookup("BRecordWithBnLEndian")
427
+ }.must_raise BinData::UnRegisteredTypeError
428
+ end
429
+
430
+ it "creates big endian version" do
431
+ obj = BRecordWithBnLEndianBe.new
432
+ obj.to_binary_s.must_equal binary("\x00\x01\x00\x02")
433
+ end
434
+
435
+ it "creates little endian version" do
436
+ obj = BRecordWithBnLEndianLe.new
437
+ obj.to_binary_s.must_equal binary("\x01\x00\x02\x00")
438
+ end
439
+
440
+ it "requires :endian as argument" do
441
+ lambda {
442
+ BRecordWithBnLEndian.new
443
+ }.must_raise ArgumentError
444
+ end
445
+
446
+ it "accepts :endian as argument" do
447
+ obj = BRecordWithBnLEndian.new(:endian => :little)
448
+ obj.to_binary_s.must_equal binary("\x01\x00\x02\x00")
449
+ end
450
+ end
451
+
381
452
  describe BinData::Record, "defined recursively" do
382
453
  class RecursiveRecord < BinData::Record
383
454
  endian :big
@@ -476,6 +547,12 @@ describe BinData::Record, "with :onlyif" do
476
547
  obj.to_binary_s.must_equal "\x03\x05"
477
548
  end
478
549
 
550
+ it "identifies if fields are included" do
551
+ obj.a?.must_equal true
552
+ obj.b?.must_equal true
553
+ obj.c?.must_equal false
554
+ end
555
+
479
556
  it "reads as lambdaed" do
480
557
  obj.read("\x01\x02")
481
558
  obj.snapshot.must_equal({:a => 1, :c => 2})
@@ -250,11 +250,11 @@ describe BinData::Struct, "with nested structs" do
250
250
  obj.c.z.must_equal 0
251
251
  end
252
252
 
253
- it "returns correct offset" do
254
- obj.b.offset.must_equal 1
255
- obj.b.w.offset.must_equal 1
256
- obj.c.offset.must_equal 3
257
- obj.c.z.offset.must_equal 4
253
+ it "returns correct abs_offset" do
254
+ obj.b.abs_offset.must_equal 1
255
+ obj.b.w.abs_offset.must_equal 1
256
+ obj.c.abs_offset.must_equal 3
257
+ obj.c.z.abs_offset.must_equal 4
258
258
  end
259
259
  end
260
260
 
@@ -313,10 +313,10 @@ describe BinData::Struct, "with bit fields" do
313
313
  end
314
314
 
315
315
  it "has correct offsets" do
316
- obj.a.offset.must_equal 0
317
- obj.b.offset.must_equal 0
318
- obj.c.offset.must_equal 1
319
- obj.d.offset.must_equal 2
316
+ obj.a.rel_offset.must_equal 0
317
+ obj.b.rel_offset.must_equal 0
318
+ obj.c.rel_offset.must_equal 1
319
+ obj.d.rel_offset.must_equal 2
320
320
  end
321
321
  end
322
322
 
@@ -338,6 +338,37 @@ describe BinData::Struct, "with nested endian" do
338
338
  end
339
339
  end
340
340
 
341
+ describe BinData::Struct, "with byte_align" do
342
+ let(:obj) {
343
+ params = { :fields => [[:int8, :a],
344
+ [:int8, :b, :byte_align => 5],
345
+ [:bit2, :c],
346
+ [:int8, :d, :byte_align => 3]] }
347
+ BinData::Struct.new(params)
348
+ }
349
+
350
+ it "has #num_bytes" do
351
+ obj.num_bytes.must_equal 10
352
+ end
353
+
354
+ it "reads" do
355
+ obj.read("\x01\x00\x00\x00\x00\x02\xc0\x00\x00\x04")
356
+ obj.snapshot.must_equal({ :a => 1, :b => 2, :c => 3, :d => 4 })
357
+ end
358
+
359
+ it "writes" do
360
+ obj.assign(:a => 1, :b => 2, :c => 3, :d => 4)
361
+ obj.to_binary_s.must_equal binary("\x01\x00\x00\x00\x00\x02\xc0\x00\x00\x04")
362
+ end
363
+
364
+ it "has correct offsets" do
365
+ obj.a.rel_offset.must_equal 0
366
+ obj.b.rel_offset.must_equal 5
367
+ obj.c.rel_offset.must_equal 6
368
+ obj.d.rel_offset.must_equal 9
369
+ end
370
+ end
371
+
341
372
  describe BinData::Struct, "with dynamically named types" do
342
373
  it "instantiates" do
343
374
  dyn = BinData::Struct.new(:name => :my_struct, :fields => [[:int8, :a, {:initial_value => 3}]])