bindata 1.5.1 → 1.6.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 (61) hide show
  1. data/ChangeLog.rdoc +7 -0
  2. data/NEWS.rdoc +11 -0
  3. data/Rakefile +6 -1
  4. data/bindata.gemspec +2 -1
  5. data/doc/manual.md +17 -9
  6. data/examples/gzip.rb +2 -2
  7. data/examples/list.rb +2 -2
  8. data/lib/bindata/alignment.rb +4 -9
  9. data/lib/bindata/array.rb +57 -51
  10. data/lib/bindata/base.rb +13 -110
  11. data/lib/bindata/base_primitive.rb +130 -75
  12. data/lib/bindata/bits.rb +5 -7
  13. data/lib/bindata/choice.rb +24 -32
  14. data/lib/bindata/dsl.rb +1 -6
  15. data/lib/bindata/framework.rb +81 -0
  16. data/lib/bindata/int.rb +5 -7
  17. data/lib/bindata/name.rb +28 -0
  18. data/lib/bindata/offset.rb +42 -53
  19. data/lib/bindata/params.rb +33 -38
  20. data/lib/bindata/struct.rb +2 -6
  21. data/lib/bindata/trace.rb +16 -16
  22. data/lib/bindata/version.rb +1 -1
  23. data/lib/bindata/virtual.rb +3 -3
  24. data/{spec/alignment_spec.rb → test/alignment_test.rb} +17 -16
  25. data/test/array_test.rb +371 -0
  26. data/test/base_primitive_test.rb +312 -0
  27. data/test/base_test.rb +183 -0
  28. data/{spec/bits_spec.rb → test/bits_test.rb} +59 -59
  29. data/test/choice_test.rb +260 -0
  30. data/{spec/spec_common.rb → test/common.rb} +33 -18
  31. data/test/count_bytes_remaining_test.rb +41 -0
  32. data/{spec/deprecated_spec.rb → test/deprecated_test.rb} +5 -7
  33. data/test/float_test.rb +72 -0
  34. data/{spec/int_spec.rb → test/int_test.rb} +34 -43
  35. data/{spec/io_spec.rb → test/io_test.rb} +70 -71
  36. data/{spec/lazy_spec.rb → test/lazy_test.rb} +38 -39
  37. data/test/offset_test.rb +93 -0
  38. data/test/params_test.rb +144 -0
  39. data/{spec/primitive_spec.rb → test/primitive_test.rb} +42 -54
  40. data/{spec/record_spec.rb → test/record_test.rb} +133 -154
  41. data/test/registry_test.rb +104 -0
  42. data/test/rest_test.rb +29 -0
  43. data/test/skip_test.rb +28 -0
  44. data/{spec/string_spec.rb → test/string_test.rb} +96 -97
  45. data/test/stringz_test.rb +127 -0
  46. data/{spec/struct_spec.rb → test/struct_test.rb} +119 -120
  47. data/{spec/system_spec.rb → test/system_test.rb} +66 -106
  48. metadata +39 -38
  49. data/lib/a.rb +0 -24
  50. data/spec/array_spec.rb +0 -331
  51. data/spec/base_primitive_spec.rb +0 -238
  52. data/spec/base_spec.rb +0 -376
  53. data/spec/choice_spec.rb +0 -263
  54. data/spec/count_bytes_remaining_spec.rb +0 -38
  55. data/spec/example.rb +0 -21
  56. data/spec/float_spec.rb +0 -37
  57. data/spec/registry_spec.rb +0 -108
  58. data/spec/rest_spec.rb +0 -26
  59. data/spec/skip_spec.rb +0 -27
  60. data/spec/stringz_spec.rb +0 -118
  61. data/tasks/rspec.rake +0 -17
data/ChangeLog.rdoc CHANGED
@@ -1,5 +1,12 @@
1
1
  = BinData Changelog
2
2
 
3
+ == Version 1.6.0 (2013-09-02)
4
+
5
+ * Added license to .gemspec
6
+ * Moved test suite from RSpec to Minitest.
7
+ * Added :assert and :asserted_value.
8
+ * :check_value has been deprecated. Use :assert instead.
9
+
3
10
  == Version 1.5.1 (2013-08-16)
4
11
 
5
12
  * Rework build system and include .gemspec. Requested by Simon Shortman.
data/NEWS.rdoc CHANGED
@@ -1,3 +1,14 @@
1
+ = 1.6.0
2
+
3
+ Added :assert as a replacement for :check_value. Note that :assert performs
4
+ the checking on assignment as well as reading.
5
+
6
+ The parameter :asserted_value is a new shortcut for combining :assert and :value
7
+ int8 :magic, :assert => 42, :value => 42
8
+
9
+ Can be written more concisely as
10
+ int8 :magic, :asserted_value => 42
11
+
1
12
  = 1.5.0
2
13
 
3
14
  Finally moved the source code to github.
data/Rakefile CHANGED
@@ -3,11 +3,16 @@ Bundler.setup
3
3
  Bundler::GemHelper.install_tasks
4
4
 
5
5
  require 'rake/clean'
6
+ require 'rake/testtask'
6
7
 
7
8
  task :clobber do
8
9
  rm_rf 'pkg'
9
10
  end
10
11
 
11
- task :default => :spec
12
+ Rake::TestTask.new do |t|
13
+ t.pattern = "test/**/*_test.rb"
14
+ end
15
+
16
+ task :default => :test
12
17
 
13
18
  Dir['tasks/**/*.rake'].each { |t| load t }
data/bindata.gemspec CHANGED
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
15
15
  s.extra_rdoc_files = ['NEWS.rdoc']
16
16
  s.rdoc_options << '--main' << 'NEWS.rdoc'
17
17
  s.files = `git ls-files`.split("\n")
18
+ s.license = 'Ruby'
18
19
 
19
20
  s.add_development_dependency('rake')
20
- s.add_development_dependency('rspec', [">= 2.10.0"])
21
+ s.add_development_dependency('minitest', "> 5.0.0")
21
22
  s.add_development_dependency('haml', ["< 4.0.0"])
22
23
  s.add_development_dependency('maruku')
23
24
  s.add_development_dependency('syntax')
data/doc/manual.md CHANGED
@@ -40,7 +40,7 @@ manipulating.
40
40
  It supports all the common datatypes that are found in structured binary
41
41
  data. Support for dependent and variable length fields is built in.
42
42
 
43
- Last updated: 2013-05-21
43
+ Last updated: 2013-09-02
44
44
 
45
45
  ## Source code
46
46
 
@@ -389,20 +389,28 @@ There are several parameters that are specific to all primitives.
389
389
  list.len #=> 3
390
390
  {:ruby}
391
391
 
392
- `:check_value`
392
+ `:assert`
393
393
 
394
- : When reading, will raise a `ValidityError` if the value read does
395
- not match the value of this parameter. This is useful when
396
- [debugging](#debugging), rather than as a general error detection
397
- system.
394
+ : When reading or assigning, will raise a `ValidityError` if the value
395
+ read or assigned does not match the value of this parameter.
398
396
 
399
- obj = BinData::String.new(:check_value => lambda { /aaa/ =~ value })
397
+ obj = BinData::String.new(:assert => lambda { /aaa/ =~ value })
400
398
  obj.read("baaa!") #=> "baaa!"
401
399
  obj.read("bbb") #=> raises ValidityError
402
400
 
403
- obj = BinData::String.new(:check_value => "foo")
401
+ obj = BinData::String.new(:assert => "foo")
404
402
  obj.read("foo") #=> "foo"
405
- obj.read("bar") #=> raises ValidityError
403
+ obj.assign("bar") #=> raises ValidityError
404
+ {:ruby}
405
+
406
+ `:asserted_value`
407
+
408
+ : A combination of `:assert` and `:value`. Used as a shortcut when
409
+ both `:assert` and `:value` have the same values. The following
410
+ are equivalent.
411
+
412
+ obj = BinData::Uint32Be.new(:assert => 42, :value => 42)
413
+ obj = BinData::Uint32Be.new(:asserted_value => 42)
406
414
  {:ruby}
407
415
 
408
416
  ## Numerics
data/examples/gzip.rb CHANGED
@@ -19,10 +19,10 @@ class Gzip
19
19
  class Header < BinData::Record
20
20
  endian :little
21
21
 
22
- uint16 :ident, :value => 0x8b1f, :check_value => 0x8b1f
22
+ uint16 :ident, :asserted_value => 0x8b1f
23
23
  uint8 :compression_method, :initial_value => DEFLATE
24
24
 
25
- bit3 :freserved, :value => 0, :check_value => 0
25
+ bit3 :freserved, :asserted_value => 0
26
26
  bit1 :fcomment, :value => lambda { comment.length > 0 ? 1 : 0 }
27
27
  bit1 :ffile_name, :value => lambda { file_name.length > 0 ? 1 : 0 }
28
28
  bit1 :fextra, :value => lambda { extra.len > 0 ? 1 : 0 }
data/examples/list.rb CHANGED
@@ -20,12 +20,12 @@ require 'bindata'
20
20
  # A first attempt at a declaration would be:
21
21
  #
22
22
  # class Atom < BinData::Record
23
- # string :tag, :length => 1, :check_value => 'a'
23
+ # string :tag, :length => 1, :assert => 'a'
24
24
  # int32be :val
25
25
  # end
26
26
  #
27
27
  # class List < BinData::Record
28
- # string :tag, :length => 1, :check_value => 'l'
28
+ # string :tag, :length => 1, :assert => 'l'
29
29
  # int32be :num, :value => lambda { vals.length }
30
30
  # array :vals, :initial_length => :num do
31
31
  # choice :selection => ??? do
@@ -13,7 +13,6 @@ module BinData
13
13
  # MyRec.read("\x12\x34") #=> {"a" => 1, "b" => 3}
14
14
  #
15
15
  class ResumeByteAlignment < BinData::Base
16
- def clear; end
17
16
  def clear?; true; end
18
17
  def assign(val); end
19
18
  def snapshot; nil; end
@@ -69,15 +68,11 @@ module BinData
69
68
  end
70
69
  end
71
70
 
72
- class BasePrimitive < BinData::Base
73
- def self.bit_aligned
74
- include BitAligned
75
- end
71
+ def BasePrimitive.bit_aligned
72
+ include BitAligned
76
73
  end
77
74
 
78
- class Primitive < BinData::BasePrimitive
79
- def self.bit_aligned
80
- fail "'bit_aligned' is not needed for BinData::Primitives"
81
- end
75
+ def Primitive.bit_aligned
76
+ fail "'bit_aligned' is not needed for BinData::Primitives"
82
77
  end
83
78
  end
data/lib/bindata/array.rb CHANGED
@@ -79,6 +79,15 @@ module BinData
79
79
 
80
80
  def initialize_shared_instance
81
81
  @element_prototype = get_parameter(:type)
82
+ if get_parameter(:read_until) == :eof
83
+ extend ReadUntilEOFPlugin
84
+ elsif has_parameter?(:read_until)
85
+ extend ReadUntilPlugin
86
+ elsif has_parameter?(:initial_length)
87
+ extend InitialLengthPlugin
88
+ end
89
+
90
+ super
82
91
  end
83
92
 
84
93
  def initialize_instance
@@ -89,10 +98,6 @@ module BinData
89
98
  @element_list.nil? or elements.all? { |el| el.clear? }
90
99
  end
91
100
 
92
- def clear
93
- initialize_instance
94
- end
95
-
96
101
  def assign(array)
97
102
  raise ArgumentError, "can't set a nil value for #{debug_name}" if array.nil?
98
103
 
@@ -234,14 +239,6 @@ module BinData
234
239
  child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor
235
240
  end
236
241
 
237
- def do_read(io) #:nodoc:
238
- if has_parameter?(:initial_length)
239
- elements.each { |el| el.do_read(io) }
240
- elsif has_parameter?(:read_until)
241
- read_until(io)
242
- end
243
- end
244
-
245
242
  def do_write(io) #:nodoc:
246
243
  elements.each { |el| el.do_write(io) }
247
244
  end
@@ -264,46 +261,8 @@ module BinData
264
261
  els.collect { |el| new_element(el) }
265
262
  end
266
263
 
267
- def read_until(io)
268
- if get_parameter(:read_until) == :eof
269
- read_until_eof(io)
270
- else
271
- read_until_condition(io)
272
- end
273
- end
274
-
275
- def read_until_eof(io)
276
- loop do
277
- element = append_new_element
278
- begin
279
- element.do_read(io)
280
- rescue EOFError, IOError
281
- elements.pop
282
- break
283
- end
284
- end
285
- end
286
-
287
- def read_until_condition(io)
288
- loop do
289
- element = append_new_element
290
- element.do_read(io)
291
- variables = { :index => self.length - 1, :element => self.last,
292
- :array => self }
293
- break if eval_parameter(:read_until, variables)
294
- end
295
- end
296
-
297
264
  def elements
298
- if @element_list.nil?
299
- @element_list = []
300
- if has_parameter?(:initial_length)
301
- eval_parameter(:initial_length).times do
302
- @element_list << new_element
303
- end
304
- end
305
- end
306
- @element_list
265
+ @element_list ||= []
307
266
  end
308
267
 
309
268
  def append_new_element
@@ -332,4 +291,51 @@ module BinData
332
291
  end
333
292
  end
334
293
  end
294
+
295
+ # Logic for the :read_until parameter
296
+ module ReadUntilPlugin
297
+ def do_read(io)
298
+ loop do
299
+ element = append_new_element
300
+ element.do_read(io)
301
+ variables = { :index => self.length - 1, :element => self.last,
302
+ :array => self }
303
+ break if eval_parameter(:read_until, variables)
304
+ end
305
+ end
306
+
307
+ end
308
+
309
+ # Logic for the :read_until => :eof parameter
310
+ module ReadUntilEOFPlugin
311
+ def do_read(io)
312
+ loop do
313
+ element = append_new_element
314
+ begin
315
+ element.do_read(io)
316
+ rescue EOFError, IOError
317
+ elements.pop
318
+ break
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ # Logic for the :initial_length parameter
325
+ module InitialLengthPlugin
326
+ def do_read(io)
327
+ elements.each { |el| el.do_read(io) }
328
+ end
329
+
330
+ def elements
331
+ if @element_list.nil?
332
+ @element_list = []
333
+ eval_parameter(:initial_length).times do
334
+ @element_list << new_element
335
+ end
336
+ end
337
+
338
+ @element_list
339
+ end
340
+ end
335
341
  end
data/lib/bindata/base.rb CHANGED
@@ -1,16 +1,15 @@
1
+ require 'bindata/framework'
1
2
  require 'bindata/io'
2
3
  require 'bindata/lazy'
4
+ require 'bindata/name'
3
5
  require 'bindata/offset'
4
6
  require 'bindata/params'
5
7
  require 'bindata/registry'
6
8
  require 'bindata/sanitize'
7
9
 
8
10
  module BinData
9
- # Error raised when unexpected results occur when reading data from IO.
10
- class ValidityError < StandardError ; end
11
-
12
11
  # ArgExtractors take the arguments passed to BinData::Base.new and
13
- # separates them into [value, parameters, parent].
12
+ # separate them into [value, parameters, parent].
14
13
  class BaseArgExtractor
15
14
  @@empty_hash = Hash.new.freeze
16
15
 
@@ -38,8 +37,10 @@ module BinData
38
37
 
39
38
  # This is the abstract base class for all data objects.
40
39
  class Base
41
- include AcceptedParametersMixin
42
- include CheckOrAdjustOffsetMixin
40
+ extend AcceptedParametersPlugin
41
+ include Framework
42
+ include CheckOrAdjustOffsetPlugin
43
+ include RegisterNamePlugin
43
44
 
44
45
  class << self
45
46
 
@@ -82,9 +83,6 @@ module BinData
82
83
  # Register all subclasses of this class.
83
84
  register_subclasses
84
85
 
85
- # The registered name may be provided explicitly.
86
- optional_parameter :name
87
-
88
86
  # Creates a new data object.
89
87
  #
90
88
  # Args are optional, but if present, must be in the following order.
@@ -97,28 +95,12 @@ module BinData
97
95
  # +parent+ is the parent data object (e.g. struct, array, choice) this
98
96
  # object resides under.
99
97
  #
100
- # == Parameters
101
- #
102
- # Parameters may be provided at initialisation to control the behaviour of
103
- # an object. These params are:
104
- #
105
- # <tt>:name</tt>:: The name that this object can be referred to may be
106
- # set explicitly. This is only useful when dynamically
107
- # generating types.
108
- # <code><pre>
109
- # BinData::Struct.new(:name => :my_struct, :fields => ...)
110
- # array = BinData::Array.new(:type => :my_struct)
111
- # </pre></code>
112
- #
113
98
  def initialize(*args)
114
99
  value, parameters, parent = extract_args(args)
115
100
 
116
101
  @params = SanitizedParameters.sanitize(parameters, self.class)
117
102
  @parent = parent
118
103
 
119
- register_prototype
120
- add_methods_for_check_or_adjust_offset
121
-
122
104
  initialize_shared_instance
123
105
  initialize_instance
124
106
  assign(value) if value
@@ -172,6 +154,11 @@ module BinData
172
154
  @params.has_parameter?(key)
173
155
  end
174
156
 
157
+ # Resets the internal state to that of a newly created object.
158
+ def clear
159
+ initialize_instance
160
+ end
161
+
175
162
  # Reads data into this data object.
176
163
  def read(io)
177
164
  io = BinData::IO.new(io) unless BinData::IO === io
@@ -274,7 +261,7 @@ module BinData
274
261
  def safe_respond_to?(symbol, include_private = false) #:nodoc:
275
262
  respond_to?(symbol, include_private)
276
263
  end
277
- alias_method :orig_respond_to?, :respond_to? #:nodoc:
264
+ alias_method :base_respond_to?, :respond_to? #:nodoc:
278
265
 
279
266
  #---------------
280
267
  private
@@ -283,12 +270,6 @@ module BinData
283
270
  self.class.arg_extractor.extract(self.class, the_args)
284
271
  end
285
272
 
286
- def register_prototype
287
- if has_parameter?(:name)
288
- RegisteredClasses.register(get_parameter(:name), self)
289
- end
290
- end
291
-
292
273
  def furthest_ancestor
293
274
  if parent.nil?
294
275
  self
@@ -306,83 +287,5 @@ module BinData
306
287
  str.dup
307
288
  end
308
289
  end
309
-
310
- ###########################################################################
311
- # To be implemented by subclasses
312
-
313
- # Performs sanity checks on the given parameters. This method converts
314
- # the parameters to the form expected by this data object.
315
- def self.sanitize_parameters!(parameters) #:nodoc:
316
- end
317
-
318
- # Initializes the state of the object. All instance variables that
319
- # are used by the object must be initialized here.
320
- def initialize_instance
321
- end
322
-
323
- # Initialises state that is shared by objects with the same parameters.
324
- #
325
- # This should only be used when optimising for performance. Instance
326
- # variables set here, and changes to the singleton class will be shared
327
- # between all objects that are initialized with the same parameters.
328
- # This method is called only once for a particular set of parameters.
329
- def initialize_shared_instance
330
- end
331
-
332
- # Resets the internal state to that of a newly created object.
333
- def clear
334
- raise NotImplementedError
335
- end
336
-
337
- # Returns true if the object has not been changed since creation.
338
- def clear?
339
- raise NotImplementedError
340
- end
341
-
342
- # Assigns the value of +val+ to this data object. Note that +val+ must
343
- # always be deep copied to ensure no aliasing problems can occur.
344
- def assign(val)
345
- raise NotImplementedError
346
- end
347
-
348
- # Returns a snapshot of this data object.
349
- def snapshot
350
- raise NotImplementedError
351
- end
352
-
353
- # Returns the debug name of +child+. This only needs to be implemented
354
- # by objects that contain child objects.
355
- def debug_name_of(child) #:nodoc:
356
- debug_name
357
- end
358
-
359
- # Returns the offset of +child+. This only needs to be implemented
360
- # by objects that contain child objects.
361
- def offset_of(child) #:nodoc:
362
- 0
363
- end
364
-
365
- # Reads the data for this data object from +io+.
366
- def do_read(io) #:nodoc:
367
- raise NotImplementedError
368
- end
369
-
370
- # Writes the value for this data to +io+.
371
- def do_write(io) #:nodoc:
372
- raise NotImplementedError
373
- end
374
-
375
- # Returns the number of bytes it will take to write this data.
376
- def do_num_bytes #:nodoc:
377
- raise NotImplementedError
378
- end
379
-
380
- # Set visibility requirements of methods to implement
381
- public :clear, :clear?, :assign, :snapshot, :debug_name_of, :offset_of
382
- protected :initialize_instance, :initialize_shared_instance
383
- protected :do_read, :do_write, :do_num_bytes
384
-
385
- # End To be implemented by subclasses
386
- ###########################################################################
387
290
  end
388
291
  end