bindata 1.2.2 → 1.3.1

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.

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
@@ -4,31 +4,29 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
4
  require 'bindata/bits'
5
5
 
6
6
  describe "Bits of size 1" do
7
- before(:each) do
8
- @bit_classes = [BinData::Bit1, BinData::Bit1le]
9
- end
7
+ let(:bit_classes) { [BinData::Bit1, BinData::Bit1le] }
10
8
 
11
9
  it "should accept true as value" do
12
- @bit_classes.each do |bit_class|
13
- obj = bit_class.new
14
- obj.value = true
15
- obj.value.should == 1
10
+ bit_classes.each do |bit_class|
11
+ subject = bit_class.new
12
+ subject.assign(true)
13
+ subject.should == 1
16
14
  end
17
15
  end
18
16
 
19
17
  it "should accept false as value" do
20
- @bit_classes.each do |bit_class|
21
- obj = bit_class.new
22
- obj.value = false
23
- obj.value.should == 0
18
+ bit_classes.each do |bit_class|
19
+ subject = bit_class.new
20
+ subject.assign(false)
21
+ subject.should == 0
24
22
  end
25
23
  end
26
24
 
27
25
  it "should accept nil as value" do
28
- @bit_classes.each do |bit_class|
29
- obj = bit_class.new
30
- obj.value = nil
31
- obj.value.should == 0
26
+ bit_classes.each do |bit_class|
27
+ subject = bit_class.new
28
+ subject.assign(nil)
29
+ subject.should == 0
32
30
  end
33
31
  end
34
32
  end
@@ -37,35 +35,35 @@ share_examples_for "All bitfields" do
37
35
 
38
36
  it "should have a sensible value of zero" do
39
37
  all_classes do |bit_class|
40
- bit_class.new.value.should be_zero
38
+ bit_class.new.should be_zero
41
39
  end
42
40
  end
43
41
 
44
42
  it "should avoid underflow" do
45
43
  all_classes do |bit_class|
46
- obj = bit_class.new
44
+ subject = bit_class.new
47
45
 
48
- obj.value = min_value - 1
49
- obj.value.should == min_value
46
+ subject.assign(min_value - 1)
47
+ subject.should == min_value
50
48
  end
51
49
  end
52
50
 
53
51
  it "should avoid overflow" do
54
52
  all_classes do |bit_class|
55
- obj = bit_class.new
53
+ subject = bit_class.new
56
54
 
57
- obj.value = max_value + 1
58
- obj.value.should == max_value
55
+ subject.assign(max_value + 1)
56
+ subject.should == max_value
59
57
  end
60
58
  end
61
59
 
62
60
  it "should assign values" do
63
61
  all_classes do |bit_class|
64
62
  some_values_within_range.each do |val|
65
- obj = bit_class.new
66
- obj.assign(val)
63
+ subject = bit_class.new
64
+ subject.assign(val)
67
65
 
68
- obj.value.should == val
66
+ subject.should == val
69
67
  end
70
68
  end
71
69
  end
@@ -73,13 +71,10 @@ share_examples_for "All bitfields" do
73
71
  it "should assign values from other bit objects" do
74
72
  all_classes do |bit_class|
75
73
  some_values_within_range.each do |val|
76
- src = bit_class.new
77
- src.assign(val)
78
-
79
- obj = bit_class.new
80
- obj.assign(src)
74
+ subject = bit_class.new
75
+ subject.assign(bit_class.new(val))
81
76
 
82
- obj.value.should == val
77
+ subject.should == val
83
78
  end
84
79
  end
85
80
  end
@@ -87,11 +82,10 @@ share_examples_for "All bitfields" do
87
82
  it "should have symmetric #read and #write" do
88
83
  all_classes do |bit_class|
89
84
  some_values_within_range.each do |val|
90
- obj = bit_class.new
91
- obj.value = val
85
+ subject = bit_class.new
86
+ subject.assign(val)
92
87
 
93
- written = obj.to_binary_s
94
- bit_class.read(written).should == val
88
+ subject.value_read_from_written.should == subject
95
89
  end
96
90
  end
97
91
  end
@@ -124,25 +118,29 @@ share_examples_for "All bitfields" do
124
118
  end
125
119
  end
126
120
 
121
+ def generate_bit_classes_to_test(endian)
122
+ bits = {}
123
+ (1 .. 50).each do |nbits|
124
+ name = (endian == :big) ? "Bit#{nbits}" : "Bit#{nbits}le"
125
+ bit_class = BinData.const_get(name)
126
+ bits[bit_class] = nbits
127
+ end
128
+ bits
129
+ end
130
+
127
131
  describe "Big endian bitfields" do
128
132
  it_should_behave_like "All bitfields"
129
133
 
130
134
  before(:all) do
131
- @bits = {}
132
- (1 .. 63).each do |nbits|
133
- bit_class = BinData.const_get("Bit#{nbits}")
134
- @bits[bit_class] = nbits
135
- end
135
+ @bits = generate_bit_classes_to_test(:big)
136
136
  end
137
137
 
138
138
  it "should read big endian value" do
139
139
  @bits.each_pair do |bit_class, nbits|
140
- obj = bit_class.new
141
-
142
140
  nbytes = (nbits + 7) / 8
143
141
  str = [0b1000_0000].pack("C") + "\000" * (nbytes - 1)
144
- obj.read(str)
145
- obj.value.should == 1 << (nbits - 1)
142
+
143
+ bit_class.read(str).should == 1 << (nbits - 1)
146
144
  end
147
145
  end
148
146
  end
@@ -151,21 +149,15 @@ describe "Little endian bitfields" do
151
149
  it_should_behave_like "All bitfields"
152
150
 
153
151
  before(:all) do
154
- @bits = {}
155
- (1 .. 63).each do |nbits|
156
- bit_class = BinData.const_get("Bit#{nbits}le")
157
- @bits[bit_class] = nbits
158
- end
152
+ @bits = generate_bit_classes_to_test(:little)
159
153
  end
160
154
 
161
155
  it "should read little endian value" do
162
156
  @bits.each_pair do |bit_class, nbits|
163
- obj = bit_class.new
164
-
165
157
  nbytes = (nbits + 7) / 8
166
158
  str = [0b0000_0001].pack("C") + "\000" * (nbytes - 1)
167
- obj.read(str)
168
- obj.value.should == 1
159
+
160
+ bit_class.read(str).should == 1
169
161
  end
170
162
  end
171
163
  end
@@ -8,6 +8,23 @@ class Chooser
8
8
  attr_accessor :choice
9
9
  end
10
10
 
11
+ class BinData::Choice
12
+ def set_chooser(chooser)
13
+ @chooser = chooser
14
+ end
15
+ def choice=(s)
16
+ @chooser.choice = s
17
+ end
18
+ end
19
+
20
+ def create_choice(choices, options = {})
21
+ chooser = Chooser.new
22
+ params = {:choices => choices, :selection => lambda { chooser.choice } }.merge(options)
23
+ choice = BinData::Choice.new(params)
24
+ choice.set_chooser(chooser)
25
+ choice
26
+ end
27
+
11
28
  describe BinData::Choice, "when instantiating" do
12
29
  it "should ensure mandatory parameters are supplied" do
13
30
  args = {}
@@ -41,170 +58,157 @@ end
41
58
 
42
59
  share_examples_for "Choice initialized with array or hash" do
43
60
  it "should be able to select the choice" do
44
- @chooser.choice = 3
45
- @data.value.should == 30
61
+ subject.choice = 3
62
+ subject.should == 30
46
63
  end
47
64
 
48
65
  it "should show the current selection" do
49
- @chooser.choice = 3
50
- @data.selection.should == 3
66
+ subject.choice = 3
67
+ subject.selection.should == 3
51
68
  end
52
69
 
53
70
  it "should not be able to directly change the current selection" do
54
71
  lambda {
55
- @data.selection = 3
72
+ subject.selection = 3
56
73
  }.should raise_error(NoMethodError)
57
74
  end
58
75
 
59
76
  it "should forward #snapshot" do
60
- @chooser.choice = 3
61
- @data.snapshot.should == 30
77
+ subject.choice = 3
78
+ subject.snapshot.should == 30
62
79
  end
63
80
 
64
81
  it "should be able to change the choice" do
65
- @chooser.choice = 3
82
+ subject.choice = 3
66
83
 
67
- @chooser.choice = 7
68
- @data.value.should == 70
84
+ subject.choice = 7
85
+ subject.should == 70
69
86
  end
70
87
 
71
88
  it "should fail if no choice has been set" do
72
- lambda { @data.value }.should raise_error(IndexError)
89
+ lambda { subject.to_s }.should raise_error(IndexError)
73
90
  end
74
91
 
75
92
  it "should not be able to select an invalid choice" do
76
- @chooser.choice = 99
77
- lambda { @data.value }.should raise_error(IndexError)
93
+ subject.choice = 99
94
+ lambda { subject.to_s }.should raise_error(IndexError)
78
95
  end
79
96
 
80
97
  it "should not be able to select a nil choice" do
81
- @chooser.choice = 1
82
- lambda { @data.value }.should raise_error(IndexError)
98
+ subject.choice = 1
99
+ lambda { subject.to_s }.should raise_error(IndexError)
83
100
  end
84
101
 
85
102
  it "should handle missing methods correctly" do
86
- @chooser.choice = 3
103
+ subject.choice = 3
87
104
 
88
- @data.should respond_to(:value)
89
- @data.should_not respond_to(:does_not_exist)
90
- lambda { @data.does_not_exist }.should raise_error(NoMethodError)
105
+ subject.should respond_to(:value)
106
+ subject.should_not respond_to(:does_not_exist)
107
+ lambda { subject.does_not_exist }.should raise_error(NoMethodError)
91
108
  end
92
109
 
93
110
  it "should delegate methods to the selected single choice" do
94
- @chooser.choice = 5
95
-
96
- @data.num_bytes.should == ExampleSingle.new.num_bytes
111
+ subject.choice = 5
112
+ subject.num_bytes.should == ExampleSingle.new.num_bytes
97
113
  end
98
114
  end
99
115
 
100
116
  describe BinData::Choice, "with sparse choices array" do
101
117
  it_should_behave_like "Choice initialized with array or hash"
102
118
 
103
- before(:each) do
104
- chooser = Chooser.new
105
- @data = BinData::Choice.new(:choices => [nil, nil, nil,
106
- [:example_single, {:value => 30}],
107
- nil,
108
- [:example_single, {:value => 50}],
109
- nil,
110
- [:example_single, {:value => 70}]],
111
- :selection => lambda { chooser.choice } )
112
- @chooser = chooser
113
- end
119
+ subject {
120
+ choices = [nil, nil, nil,
121
+ [:example_single, {:value => 30}], nil,
122
+ [:example_single, {:value => 50}], nil,
123
+ [:example_single, {:value => 70}]]
124
+ create_choice(choices)
125
+ }
114
126
  end
115
127
 
116
128
  describe BinData::Choice, "with choices hash" do
117
129
  it_should_behave_like "Choice initialized with array or hash"
118
130
 
119
- before(:each) do
120
- chooser = Chooser.new
121
- @data = BinData::Choice.new(:choices => {3 => [:example_single, {:value => 30}],
122
- 5 => [:example_single, {:value => 50}],
123
- 7 => [:example_single, {:value => 70}]},
124
- :selection => lambda { chooser.choice } )
125
- @chooser = chooser
126
- end
131
+ subject {
132
+ choices = {3 => [:example_single, {:value => 30}],
133
+ 5 => [:example_single, {:value => 50}],
134
+ 7 => [:example_single, {:value => 70}]}
135
+ create_choice(choices)
136
+ }
127
137
  end
128
138
 
129
139
  describe BinData::Choice, "with single values" do
130
- before(:each) do
131
- chooser = Chooser.new
132
- @data = BinData::Choice.new(:choices => {3 => :example_single,
133
- 5 => :example_single,
134
- 7 => :example_single,},
135
- :selection => lambda { chooser.choice } )
136
- @chooser = chooser
137
- end
140
+ subject {
141
+ choices = {3 => :example_single,
142
+ 5 => :example_single,
143
+ 7 => :example_single}
144
+ create_choice(choices)
145
+ }
138
146
 
139
147
  it "should assign raw values" do
140
- @chooser.choice = 3
141
- @data.value = 254
142
- @data.value.should == 254
148
+ subject.choice = 3
149
+ subject.assign(254)
150
+ subject.should == 254
143
151
  end
144
152
 
145
153
  it "should assign Single values" do
146
- obj = ExampleSingle.new
147
- obj.value = 11
154
+ obj = ExampleSingle.new(11)
148
155
 
149
- @chooser.choice = 3
150
- @data.value = obj
151
- @data.value.should == 11
156
+ subject.choice = 3
157
+ subject.assign(obj)
158
+ subject.should == 11
152
159
  end
153
160
 
154
161
  it "should clear" do
155
- @chooser.choice = 3
156
- @data.value = 254
162
+ subject.choice = 3
163
+ subject.assign(254)
157
164
 
158
- @data.clear
159
- @data.value.should be_zero
165
+ subject.clear
166
+ subject.should be_zero
160
167
  end
161
168
 
162
169
  it "should be clear on initialisation" do
163
- @chooser.choice = 3
170
+ subject.choice = 3
164
171
 
165
- @data.should be_clear
172
+ subject.should be_clear
166
173
  end
167
174
 
168
175
  it "should not be clear after assignment" do
169
- @chooser.choice = 3
170
- @data.value = 254
176
+ subject.choice = 3
177
+ subject.assign(254)
171
178
 
172
- @data.should_not be_clear
179
+ subject.should_not be_clear
173
180
  end
174
181
 
175
182
  it "should not copy value when changing selection" do
176
- @chooser.choice = 3
177
- @data.value = 254
183
+ subject.choice = 3
184
+ subject.assign(254)
178
185
 
179
- @chooser.choice = 7
180
- @data.value.should_not == 254
186
+ subject.choice = 7
187
+ subject.should_not == 254
181
188
  end
182
189
 
183
190
  it "should behave as value" do
184
- @chooser.choice = 3
185
- @data.value = 5
191
+ subject.choice = 3
192
+ subject.assign(5)
186
193
 
187
- (@data + 1).should == 6
188
- (1 + @data).should == 6
194
+ (subject + 1).should == 6
195
+ (1 + subject).should == 6
189
196
  end
190
197
  end
191
198
 
192
199
  describe BinData::Choice, "with copy_on_change => true" do
193
- before(:each) do
194
- chooser = Chooser.new
195
- @data = BinData::Choice.new(:choices => {3 => :example_single,
196
- 5 => :example_single,
197
- 7 => :example_single,},
198
- :selection => lambda { chooser.choice },
199
- :copy_on_change => true)
200
- @chooser = chooser
201
- end
200
+ subject {
201
+ choices = {3 => :example_single,
202
+ 5 => :example_single,
203
+ 7 => :example_single}
204
+ create_choice(choices, :copy_on_change => true)
205
+ }
202
206
 
203
207
  it "should copy value when changing selection" do
204
- @chooser.choice = 3
205
- @data.value = 254
208
+ subject.choice = 3
209
+ subject.assign(254)
206
210
 
207
- @chooser.choice = 7
208
- @data.value.should == 254
211
+ subject.choice = 7
212
+ subject.should == 254
209
213
  end
210
214
  end