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.

Files changed (47) hide show
  1. data/ChangeLog +18 -0
  2. data/NEWS +59 -0
  3. data/README +22 -23
  4. data/TODO +18 -12
  5. data/examples/gzip.rb +4 -4
  6. data/lib/bindata.rb +4 -3
  7. data/lib/bindata/array.rb +202 -132
  8. data/lib/bindata/base.rb +147 -166
  9. data/lib/bindata/{single.rb → base_primitive.rb} +82 -56
  10. data/lib/bindata/bits.rb +31 -770
  11. data/lib/bindata/choice.rb +157 -82
  12. data/lib/bindata/float.rb +25 -27
  13. data/lib/bindata/int.rb +144 -177
  14. data/lib/bindata/io.rb +59 -49
  15. data/lib/bindata/lazy.rb +80 -50
  16. data/lib/bindata/params.rb +134 -26
  17. data/lib/bindata/{single_value.rb → primitive.rb} +71 -64
  18. data/lib/bindata/{multi_value.rb → record.rb} +52 -70
  19. data/lib/bindata/registry.rb +49 -17
  20. data/lib/bindata/rest.rb +6 -10
  21. data/lib/bindata/sanitize.rb +55 -70
  22. data/lib/bindata/string.rb +60 -42
  23. data/lib/bindata/stringz.rb +34 -35
  24. data/lib/bindata/struct.rb +197 -152
  25. data/lib/bindata/trace.rb +35 -0
  26. data/spec/array_spec.rb +128 -112
  27. data/spec/{single_spec.rb → base_primitive_spec.rb} +102 -61
  28. data/spec/base_spec.rb +190 -185
  29. data/spec/bits_spec.rb +126 -98
  30. data/spec/choice_spec.rb +89 -98
  31. data/spec/example.rb +19 -0
  32. data/spec/float_spec.rb +28 -44
  33. data/spec/int_spec.rb +217 -127
  34. data/spec/io_spec.rb +41 -24
  35. data/spec/lazy_spec.rb +95 -49
  36. data/spec/primitive_spec.rb +191 -0
  37. data/spec/{multi_value_spec.rb → record_spec.rb} +124 -89
  38. data/spec/registry_spec.rb +53 -12
  39. data/spec/rest_spec.rb +2 -3
  40. data/spec/sanitize_spec.rb +47 -73
  41. data/spec/spec_common.rb +13 -1
  42. data/spec/string_spec.rb +34 -23
  43. data/spec/stringz_spec.rb +10 -18
  44. data/spec/struct_spec.rb +91 -63
  45. data/spec/system_spec.rb +291 -0
  46. metadata +12 -8
  47. data/spec/single_value_spec.rb +0 -131
@@ -3,46 +3,20 @@
3
3
  require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
4
4
  require 'bindata'
5
5
 
6
- describe BinData::MultiValue, "with hidden fields" do
7
- before(:all) do
8
- eval <<-END
9
- class HiddenMultiValue < BinData::MultiValue
10
- hide :b, 'c'
11
- int8 :a
12
- int8 'b', :initial_value => 10
13
- int8 :c
14
- int8 :d, :value => :b
15
- end
16
- END
17
- end
18
-
19
- before(:each) do
20
- @obj = HiddenMultiValue.new
21
- end
22
-
23
- it "should only show fields that aren't hidden" do
24
- @obj.field_names.should == ["a", "d"]
25
- end
26
-
27
- it "should be able to access hidden fields directly" do
28
- @obj.b.should == 10
29
- @obj.c = 15
30
- @obj.c.should == 15
31
-
32
- @obj.should respond_to(:b=)
6
+ describe BinData::Record, "when defining" do
7
+ it "should allow inheriting from deprecated MultiValue" do
8
+ lambda {
9
+ eval <<-END
10
+ class SubclassMultiValue < BinData::MultiValue
11
+ end
12
+ END
13
+ }.should_not raise_error
33
14
  end
34
15
 
35
- it "should not include hidden fields in snapshot" do
36
- @obj.b = 5
37
- @obj.snapshot.should == {"a" => 0, "d" => 5}
38
- end
39
- end
40
-
41
- describe BinData::MultiValue, "when defining" do
42
16
  it "should fail on non registered types" do
43
17
  lambda {
44
18
  eval <<-END
45
- class BadTypeMultiValue < BinData::MultiValue
19
+ class BadTypeRecord < BinData::Record
46
20
  non_registerd_type :a
47
21
  end
48
22
  END
@@ -52,7 +26,7 @@ describe BinData::MultiValue, "when defining" do
52
26
  it "should fail on duplicate names" do
53
27
  lambda {
54
28
  eval <<-END
55
- class DuplicateNameMultiValue < BinData::MultiValue
29
+ class DuplicateNameRecord < BinData::Record
56
30
  int8 :a
57
31
  int8 :b
58
32
  int8 :a
@@ -64,7 +38,7 @@ describe BinData::MultiValue, "when defining" do
64
38
  it "should fail on reserved names" do
65
39
  lambda {
66
40
  eval <<-END
67
- class ReservedNameMultiValue < BinData::MultiValue
41
+ class ReservedNameRecord < BinData::Record
68
42
  int8 :a
69
43
  int8 :invert # from Hash.instance_methods
70
44
  end
@@ -75,7 +49,7 @@ describe BinData::MultiValue, "when defining" do
75
49
  it "should fail when field name shadows an existing method" do
76
50
  lambda {
77
51
  eval <<-END
78
- class ExistingNameMultiValue < BinData::MultiValue
52
+ class ExistingNameRecord < BinData::Record
79
53
  int8 :object_id
80
54
  end
81
55
  END
@@ -85,7 +59,7 @@ describe BinData::MultiValue, "when defining" do
85
59
  it "should fail on unknown endian" do
86
60
  lambda {
87
61
  eval <<-END
88
- class BadEndianMultiValue < BinData::MultiValue
62
+ class BadEndianRecord < BinData::Record
89
63
  endian 'a bad value'
90
64
  end
91
65
  END
@@ -93,10 +67,45 @@ describe BinData::MultiValue, "when defining" do
93
67
  end
94
68
  end
95
69
 
96
- describe BinData::MultiValue, "with multiple fields" do
70
+ describe BinData::Record, "with hidden fields" do
71
+ before(:all) do
72
+ eval <<-END
73
+ class HiddenRecord < BinData::Record
74
+ hide :b, 'c'
75
+ int8 :a
76
+ int8 'b', :initial_value => 10
77
+ int8 :c
78
+ int8 :d, :value => :b
79
+ end
80
+ END
81
+ end
82
+
83
+ before(:each) do
84
+ @obj = HiddenRecord.new
85
+ end
86
+
87
+ it "should only show fields that aren't hidden" do
88
+ @obj.field_names.should == ["a", "d"]
89
+ end
90
+
91
+ it "should be able to access hidden fields directly" do
92
+ @obj.b.should == 10
93
+ @obj.c = 15
94
+ @obj.c.should == 15
95
+
96
+ @obj.should respond_to(:b=)
97
+ end
98
+
99
+ it "should not include hidden fields in snapshot" do
100
+ @obj.b = 5
101
+ @obj.snapshot.should == {"a" => 0, "d" => 5}
102
+ end
103
+ end
104
+
105
+ describe BinData::Record, "with multiple fields" do
97
106
  before(:all) do
98
107
  eval <<-END
99
- class MultiFieldMultiValue < BinData::MultiValue
108
+ class MultiFieldRecord < BinData::Record
100
109
  int8 :a
101
110
  int8 :b
102
111
  end
@@ -104,7 +113,7 @@ describe BinData::MultiValue, "with multiple fields" do
104
113
  end
105
114
 
106
115
  before(:each) do
107
- @obj = MultiFieldMultiValue.new
116
+ @obj = MultiFieldRecord.new
108
117
  @obj.a = 1
109
118
  @obj.b = 2
110
119
  end
@@ -116,35 +125,30 @@ describe BinData::MultiValue, "with multiple fields" do
116
125
  end
117
126
 
118
127
  it "should identify accepted parameters" do
119
- BinData::MultiValue.internal_parameters.should include(:hide)
120
- BinData::MultiValue.internal_parameters.should include(:endian)
128
+ BinData::Record.accepted_internal_parameters.should include(:hide)
129
+ BinData::Record.accepted_internal_parameters.should include(:endian)
121
130
  end
122
131
 
123
132
  it "should clear" do
124
133
  @obj.a = 6
125
134
  @obj.clear
126
- @obj.clear?.should be_true
135
+ @obj.should be_clear
127
136
  end
128
137
 
129
138
  it "should clear individual elements" do
130
139
  @obj.a = 6
131
140
  @obj.b = 7
132
141
  @obj.clear(:a)
133
- @obj.clear?(:a).should be_true
134
- @obj.clear?(:b).should be_false
142
+ @obj.should be_clear(:a)
143
+ @obj.should_not be_clear(:b)
135
144
  end
136
145
 
137
146
  it "should write ordered" do
138
- io = StringIO.new
139
- @obj.write(io)
140
-
141
- io.rewind
142
- io.read.should == "\x01\x02"
147
+ @obj.to_binary_s.should == "\x01\x02"
143
148
  end
144
149
 
145
150
  it "should read ordered" do
146
- io = StringIO.new "\x03\x04"
147
- @obj.read(io)
151
+ @obj.read("\x03\x04")
148
152
 
149
153
  @obj.a.should == 3
150
154
  @obj.b.should == 4
@@ -166,29 +170,29 @@ describe BinData::MultiValue, "with multiple fields" do
166
170
  end
167
171
  end
168
172
 
169
- describe BinData::MultiValue, "with nested structs" do
173
+ describe BinData::Record, "with nested structs" do
170
174
  before(:all) do
171
175
  eval <<-END
172
- class MultiValueInner1 < BinData::MultiValue
176
+ class Inner1Record < BinData::Record
173
177
  int8 :w, :initial_value => 3
174
178
  int8 :x, :value => :the_val
175
179
  end
176
180
 
177
- class MultiValueInner2 < BinData::MultiValue
181
+ class Inner2Record < BinData::Record
178
182
  int8 :y, :value => lambda { parent.b.w }
179
183
  int8 :z
180
184
  end
181
185
 
182
- class MultiValueOuter < BinData::MultiValue
186
+ class RecordOuter < BinData::Record
183
187
  int8 :a, :initial_value => 6
184
- multi_value_inner1 :b, :the_val => :a
185
- multi_value_inner2 :c
188
+ inner1_record :b, :the_val => :a
189
+ inner2_record :c
186
190
  end
187
191
  END
188
192
  end
189
193
 
190
194
  before(:each) do
191
- @obj = MultiValueOuter.new
195
+ @obj = RecordOuter.new
192
196
  end
193
197
 
194
198
  it "should included nested field names" do
@@ -202,16 +206,18 @@ describe BinData::MultiValue, "with nested structs" do
202
206
  @obj.c.y.should == 3
203
207
  end
204
208
 
205
- it "should return correct offset of" do
206
- @obj.offset_of("b").should == 1
207
- @obj.offset_of("c").should == 3
209
+ it "should return correct offset" do
210
+ @obj.b.offset.should == 1
211
+ @obj.b.w.offset.should == 1
212
+ @obj.c.offset.should == 3
213
+ @obj.c.z.offset.should == 4
208
214
  end
209
215
  end
210
216
 
211
- describe BinData::MultiValue, "with an endian defined" do
217
+ describe BinData::Record, "with an endian defined" do
212
218
  before(:all) do
213
219
  eval <<-END
214
- class MultiValueWithEndian < BinData::MultiValue
220
+ class RecordWithEndian < BinData::Record
215
221
  endian :little
216
222
 
217
223
  uint16 :a
@@ -225,7 +231,7 @@ describe BinData::MultiValue, "with an endian defined" do
225
231
  end
226
232
 
227
233
  before(:each) do
228
- @obj = MultiValueWithEndian.new
234
+ @obj = RecordWithEndian.new
229
235
  end
230
236
 
231
237
  it "should use correct endian" do
@@ -240,58 +246,54 @@ describe BinData::MultiValue, "with an endian defined" do
240
246
 
241
247
  expected = [1, 2.0, 3, 4, 5, 6, 7, 8].pack('veCCVvNv')
242
248
 
243
- io = StringIO.new
244
- @obj.write(io)
245
-
246
- io.rewind
247
- io.read.should == expected
249
+ @obj.to_binary_s.should == expected
248
250
  end
249
251
  end
250
252
 
251
- describe BinData::MultiValue, "defined recursively" do
253
+ describe BinData::Record, "defined recursively" do
252
254
  before(:all) do
253
255
  eval <<-END
254
- class RecursiveMultiValue < BinData::MultiValue
256
+ class RecursiveRecord < BinData::Record
255
257
  endian :big
256
258
  uint16 :val
257
259
  uint8 :has_nxt, :value => lambda { nxt.clear? ? 0 : 1 }
258
- recursive_multi_value :nxt, :onlyif => lambda { has_nxt > 0 }
260
+ recursive_record :nxt, :onlyif => lambda { has_nxt > 0 }
259
261
  end
260
262
  END
261
263
  end
262
264
 
263
265
  it "should be able to be created" do
264
- obj = RecursiveMultiValue.new
266
+ obj = RecursiveRecord.new
265
267
  end
266
268
 
267
269
  it "should read" do
268
270
  str = "\x00\x01\x01\x00\x02\x01\x00\x03\x00"
269
- obj = RecursiveMultiValue.read(str)
271
+ obj = RecursiveRecord.read(str)
270
272
  obj.val.should == 1
271
273
  obj.nxt.val.should == 2
272
274
  obj.nxt.nxt.val.should == 3
273
275
  end
274
276
 
275
277
  it "should be assignable on demand" do
276
- obj = RecursiveMultiValue.new
278
+ obj = RecursiveRecord.new
277
279
  obj.val = 13
278
280
  obj.nxt.val = 14
279
281
  obj.nxt.nxt.val = 15
280
282
  end
281
283
 
282
284
  it "should write" do
283
- obj = RecursiveMultiValue.new
285
+ obj = RecursiveRecord.new
284
286
  obj.val = 5
285
287
  obj.nxt.val = 6
286
288
  obj.nxt.nxt.val = 7
287
- obj.to_s.should == "\x00\x05\x01\x00\x06\x01\x00\x07\x00"
289
+ obj.to_binary_s.should == "\x00\x05\x01\x00\x06\x01\x00\x07\x00"
288
290
  end
289
291
  end
290
292
 
291
- describe BinData::MultiValue, "with custom mandatory parameters" do
293
+ describe BinData::Record, "with custom mandatory parameters" do
292
294
  before(:all) do
293
295
  eval <<-END
294
- class MandatoryMultiValue < BinData::MultiValue
296
+ class MandatoryRecord < BinData::Record
295
297
  mandatory_parameter :arg1
296
298
 
297
299
  uint8 :a, :value => :arg1
@@ -300,19 +302,19 @@ describe BinData::MultiValue, "with custom mandatory parameters" do
300
302
  end
301
303
 
302
304
  it "should raise error if mandatory parameter is not supplied" do
303
- lambda { MandatoryMultiValue.new }.should raise_error(ArgumentError)
305
+ lambda { MandatoryRecord.new }.should raise_error(ArgumentError)
304
306
  end
305
307
 
306
308
  it "should use mandatory parameter" do
307
- obj = MandatoryMultiValue.new(:arg1 => 5)
309
+ obj = MandatoryRecord.new(:arg1 => 5)
308
310
  obj.a.should == 5
309
311
  end
310
312
  end
311
313
 
312
- describe BinData::MultiValue, "with custom default parameters" do
314
+ describe BinData::Record, "with custom default parameters" do
313
315
  before(:all) do
314
316
  eval <<-END
315
- class DefaultMultiValue < BinData::MultiValue
317
+ class DefaultRecord < BinData::Record
316
318
  default_parameter :arg1 => 5
317
319
 
318
320
  uint8 :a, :value => :arg1
@@ -321,16 +323,49 @@ describe BinData::MultiValue, "with custom default parameters" do
321
323
  end
322
324
 
323
325
  it "should not raise error if default parameter is not supplied" do
324
- lambda { DefaultMultiValue.new }.should_not raise_error(ArgumentError)
326
+ lambda { DefaultRecord.new }.should_not raise_error(ArgumentError)
325
327
  end
326
328
 
327
329
  it "should use default parameter" do
328
- obj = DefaultMultiValue.new
330
+ obj = DefaultRecord.new
329
331
  obj.a.should == 5
330
332
  end
331
333
 
332
334
  it "should be able to override default parameter" do
333
- obj = DefaultMultiValue.new(:arg1 => 7)
335
+ obj = DefaultRecord.new(:arg1 => 7)
334
336
  obj.a.should == 7
335
337
  end
336
338
  end
339
+
340
+ describe BinData::Record, "with :onlyif" do
341
+ before(:all) do
342
+ eval <<-END
343
+ class OnlyIfRecord < BinData::Record
344
+ uint8 :a, :initial_value => 3
345
+ uint8 :b, :initial_value => 5, :onlyif => lambda { a == 3 }
346
+ uint8 :c, :initial_value => 7, :onlyif => lambda { a != 3 }
347
+ end
348
+ END
349
+ end
350
+
351
+ before(:each) do
352
+ @obj = OnlyIfRecord.new
353
+ end
354
+
355
+ it "should have correct num_bytes" do
356
+ @obj.num_bytes.should == 2
357
+ end
358
+
359
+ it "should have expected snapshot" do
360
+ @obj.snapshot.should == {"a" => 3, "b" => 5}
361
+ end
362
+
363
+ it "should read as expected" do
364
+ @obj.read("\x01\x02")
365
+ @obj.snapshot.should == {"a" => 1, "c" => 2}
366
+ end
367
+
368
+ it "should write as expected" do
369
+ @obj.to_binary_s.should == "\x03\x05"
370
+ end
371
+ end
@@ -4,17 +4,28 @@ require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
4
4
  require 'bindata/registry'
5
5
 
6
6
  describe BinData::Registry do
7
+ before(:all) do
8
+ A = Class.new
9
+ B = Class.new
10
+ C = Class.new
11
+ D = Class.new
12
+ end
13
+
7
14
  before(:each) do
8
- @r = BinData::Registry.instance
15
+ @r = BinData::Registry.new
9
16
  end
10
17
 
11
- it "should be a singleton" do
12
- BinData::Registry.instance.should == BinData::Registry.instance
18
+ it "should determine if a name is registered" do
19
+ @r.register('A', A)
20
+
21
+ @r.is_registered?('a').should be_true
22
+ end
23
+
24
+ it "should determine if a name is not registered" do
25
+ @r.is_registered?('xyz').should be_false
13
26
  end
14
27
 
15
28
  it "should lookup registered names" do
16
- A = Class.new
17
- B = Class.new
18
29
  @r.register('ASubClass', A)
19
30
  @r.register('AnotherSubClass', B)
20
31
 
@@ -26,22 +37,52 @@ describe BinData::Registry do
26
37
  @r.lookup('a_non_existent_sub_class').should be_nil
27
38
  end
28
39
 
40
+ it "should allow overriding of registered classes" do
41
+ @r.register('A', A)
42
+ @r.register('A', B)
43
+
44
+ @r.lookup('a').should == B
45
+ end
46
+
29
47
  it "should convert CamelCase to underscores" do
30
- @r.register('CamelCase', A).should == 'camel_case'
48
+ @r.underscore_name('CamelCase').should == 'camel_case'
31
49
  end
32
50
 
33
51
  it "should convert adjacent caps camelCase to underscores" do
34
- @r.register('XYZCamelCase', A).should == 'xyz_camel_case'
52
+ @r.underscore_name('XYZCamelCase').should == 'xyz_camel_case'
35
53
  end
36
54
 
37
55
  it "should ignore the outer nestings of classes" do
38
- @r.register('A::B::C', A).should == 'c'
56
+ @r.underscore_name('A::B::C').should == 'c'
39
57
  end
40
58
 
41
- it "should allow overriding of registered classes" do
42
- @r.register('A', A)
43
- @r.register('A', B)
59
+ it "should lookup integers with endian" do
60
+ # @r.register("Int24be", A)
61
+ # @r.register("Int24le", B)
62
+ # @r.register("Uint24be", C)
63
+ # @r.register("Uint24le", D)
64
+ #
65
+ # @r.lookup("int24", :big).should == A
66
+ # @r.lookup("int24", :little).should == B
67
+ # @r.lookup("uint24", :big).should == C
68
+ # @r.lookup("uint24", :little).should == D
69
+ end
44
70
 
45
- @r.lookup('a').should == B
71
+ it "should not lookup integers without endian" do
72
+ # @r.register("Int24be", A)
73
+
74
+ # @r.lookup("int24").should be_nil
75
+ end
76
+
77
+ it "should lookup floats with endian" do
78
+ # @r.register("FloatBe", A)
79
+ # @r.register("FloatLe", B)
80
+ # @r.register("DoubleBe", C)
81
+ # @r.register("DoubleLe", D)
82
+ #
83
+ # @r.lookup("float", :big).should == A
84
+ # @r.lookup("float", :little).should == B
85
+ # @r.lookup("double", :big).should == C
86
+ # @r.lookup("double", :little).should == D
46
87
  end
47
88
  end