bindata 1.8.3 → 2.0.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.

@@ -6,11 +6,13 @@ module BinData
6
6
 
7
7
  module BitField #:nodoc: all
8
8
  class << self
9
- def define_class(name, nbits, endian, signed = :unsigned)
9
+ def define_class(nbits, endian, signed = :unsigned)
10
+ name = ((signed == :signed ) ? "Sbit" : "Bit") + nbits.to_s
11
+ name << "le" if endian == :little
10
12
  unless BinData.const_defined?(name)
11
13
  BinData.module_eval <<-END
12
14
  class #{name} < BinData::BasePrimitive
13
- BitField.define_methods(self, #{nbits.inspect}, #{endian.inspect}, #{signed.inspect})
15
+ BitField.define_methods(self, #{nbits}, :#{endian}, :#{signed})
14
16
  end
15
17
  END
16
18
  end
@@ -20,34 +22,27 @@ module BinData
20
22
 
21
23
  def define_methods(bit_class, nbits, endian, signed)
22
24
  bit_class.module_eval <<-END
23
- #{create_params_code(nbits)}
24
-
25
25
  def assign(val)
26
- #{create_nbits_code(nbits)}
27
26
  #{create_clamp_code(nbits, signed)}
28
27
  super(val)
29
28
  end
30
29
 
31
30
  def do_write(io)
32
- #{create_nbits_code(nbits)}
33
31
  val = _value
34
- #{create_int2uint_code(nbits, signed)}
32
+ #{create_int2uint_code(nbits) if signed == :signed}
35
33
  io.writebits(val, #{nbits}, :#{endian})
36
34
  end
37
35
 
38
36
  def do_num_bytes
39
- #{create_nbits_code(nbits)}
40
- #{create_do_num_bytes_code(nbits)}
37
+ #{nbits / 8.0}
41
38
  end
42
39
 
43
40
  #---------------
44
41
  private
45
42
 
46
-
47
43
  def read_and_return_value(io)
48
- #{create_nbits_code(nbits)}
49
44
  val = io.readbits(#{nbits}, :#{endian})
50
- #{create_uint2int_code(nbits, signed)}
45
+ #{create_uint2int_code(nbits) if signed == :signed}
51
46
  val
52
47
  end
53
48
 
@@ -57,51 +52,7 @@ module BinData
57
52
  END
58
53
  end
59
54
 
60
- def create_params_code(nbits)
61
- if nbits == :nbits
62
- "mandatory_parameter :nbits"
63
- else
64
- ""
65
- end
66
- end
67
-
68
- def create_nbits_code(nbits)
69
- if nbits == :nbits
70
- "nbits = eval_parameter(:nbits)"
71
- else
72
- ""
73
- end
74
- end
75
-
76
- def create_do_num_bytes_code(nbits)
77
- if nbits == :nbits
78
- "nbits / 8.0"
79
- else
80
- nbits / 8.0
81
- end
82
- end
83
-
84
55
  def create_clamp_code(nbits, signed)
85
- if nbits == :nbits
86
- create_dynamic_clamp_code(nbits, signed)
87
- else
88
- create_fixed_clamp_code(nbits, signed)
89
- end
90
- end
91
-
92
- def create_dynamic_clamp_code(nbits, signed)
93
- if signed == :signed
94
- max = "max = (1 << (nbits - 1)) - 1"
95
- min = "min = -(max + 1)"
96
- else
97
- max = "max = (1 << nbits) - 1"
98
- min = "min = 0"
99
- end
100
-
101
- "#{max}; #{min}; val = (val < min) ? min : (val > max) ? max : val"
102
- end
103
-
104
- def create_fixed_clamp_code(nbits, signed)
105
56
  if nbits == 1 and signed == :signed
106
57
  raise "signed bitfield must have more than one bit"
107
58
  end
@@ -124,50 +75,30 @@ module BinData
124
75
  "val = #{clamp}"
125
76
  end
126
77
 
127
- def create_int2uint_code(nbits, signed)
128
- if signed != :signed
129
- ""
130
- elsif nbits == :nbits
131
- "val &= (1 << nbits) - 1"
132
- else
133
- "val &= #{(1 << nbits) - 1}"
134
- end
78
+ def create_int2uint_code(nbits)
79
+ "val = val & #{(1 << nbits) - 1}"
135
80
  end
136
81
 
137
- def create_uint2int_code(nbits, signed)
138
- if signed != :signed
139
- ""
140
- elsif nbits == :nbits
141
- "val -= (1 << nbits) if (val >= (1 << (nbits - 1)))"
142
- else
143
- "val -= #{1 << nbits} if (val >= #{1 << (nbits - 1)})"
144
- end
82
+ def create_uint2int_code(nbits)
83
+ "val = val - #{1 << nbits} if (val >= #{1 << (nbits - 1)})"
145
84
  end
146
85
  end
147
86
  end
148
87
 
149
- # Create classes for dynamic bitfields
150
- {
151
- "Bit" => :big,
152
- "BitLe" => :little,
153
- "Sbit" => [:big, :signed],
154
- "SbitLe" => [:little, :signed],
155
- }.each_pair { |name, args| BitField.define_class(name, :nbits, *args) }
156
-
157
88
  # Create classes on demand
158
89
  module BitFieldFactory
159
90
  def const_missing(name)
160
91
  mappings = {
161
- /^Bit(\d+)$/ => :big,
162
- /^Bit(\d+)le$/ => :little,
163
- /^Sbit(\d+)$/ => [:big, :signed],
92
+ /^Bit(\d+)$/ => :big,
93
+ /^Bit(\d+)le$/ => :little,
94
+ /^Sbit(\d+)$/ => [:big, :signed],
164
95
  /^Sbit(\d+)le$/ => [:little, :signed]
165
96
  }
166
97
 
167
98
  mappings.each_pair do |regex, args|
168
99
  if regex =~ name.to_s
169
100
  nbits = $1.to_i
170
- return BitField.define_class(name, nbits, *args)
101
+ return BitField.define_class(nbits, *args)
171
102
  end
172
103
  end
173
104
 
@@ -76,7 +76,7 @@ module BinData
76
76
  @type = get_parameter(:type).instantiate(nil, self)
77
77
  end
78
78
 
79
- def clear?
79
+ def clear? #:nodoc:
80
80
  @type.clear?
81
81
  end
82
82
 
@@ -125,24 +125,40 @@ module BinData
125
125
  selection
126
126
  end
127
127
 
128
- def safe_respond_to?(symbol, include_private = false) #:nodoc:
129
- base_respond_to?(symbol, include_private)
128
+ def clear? #:nodoc:
129
+ current_choice.clear?
130
+ end
131
+
132
+ def assign(val)
133
+ current_choice.assign(val)
134
+ end
135
+
136
+ def snapshot
137
+ current_choice.snapshot
130
138
  end
131
139
 
132
140
  def respond_to?(symbol, include_private = false) #:nodoc:
133
141
  current_choice.respond_to?(symbol, include_private) || super
134
142
  end
135
143
 
144
+ def safe_respond_to?(symbol, include_private = false) #:nodoc:
145
+ base_respond_to?(symbol, include_private)
146
+ end
147
+
136
148
  def method_missing(symbol, *args, &block) #:nodoc:
137
149
  current_choice.__send__(symbol, *args, &block)
138
150
  end
139
151
 
140
- %w(clear? assign snapshot do_read do_write do_num_bytes).each do |m|
141
- self.module_eval <<-END
142
- def #{m}(*args)
143
- current_choice.#{m}(*args)
144
- end
145
- END
152
+ def do_read(io) #:nodoc:
153
+ current_choice.do_read(io)
154
+ end
155
+
156
+ def do_write(io) #:nodoc:
157
+ current_choice.do_write(io)
158
+ end
159
+
160
+ def do_num_bytes #:nodoc:
161
+ current_choice.do_num_bytes
146
162
  end
147
163
 
148
164
  #---------------
@@ -1,31 +1,14 @@
1
- # Implement Kernel#instance_exec for Ruby 1.8.6 and below
2
- unless Object.respond_to? :instance_exec
3
- module Kernel
4
- # Taken from http://eigenclass.org/hiki/instance_exec
5
- def instance_exec(*args, &block)
6
- mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
7
- Object.class_eval{ define_method(mname, &block) }
8
- begin
9
- ret = send(mname, *args)
10
- ensure
11
- Object.class_eval{ undef_method(mname) } rescue nil
12
- end
13
- ret
14
- end
15
- end
16
- end
17
-
18
1
  module BinData
19
2
  class Base
20
3
 
21
4
  # Don't override initialize. If you are defining a new kind of datatype
22
5
  # (list, array, choice etc) then put your initialization code in
23
- # #initialize_instance. BinData objects might be initialized as prototypes
24
- # and your initialization code may not be called.
6
+ # #initialize_instance. This is because BinData objects can be initialized
7
+ # as prototypes and your initialization code may not be called.
25
8
  #
26
9
  # If you're subclassing BinData::Record, you are definitely doing the wrong
27
10
  # thing. Read the documentation on how to use BinData.
28
- # http://github.com/dmendel/bindata/wiki/Records
11
+ # http://bindata.rubyforge.org/manual.html#records
29
12
  alias_method :initialize_without_warning, :initialize
30
13
  def initialize_with_warning(*args)
31
14
  owner = method(:initialize).owner
@@ -46,11 +29,5 @@ module BinData
46
29
  end
47
30
  end
48
31
 
49
- # #offset has been renamed to #abs_offset.
50
- # Eventually #rel_offset will be renamed to #offset.
51
- def offset
52
- warn "#offset is deprecated in #{debug_name}. Use #abs_offset instead"
53
- abs_offset
54
- end
55
32
  end
56
33
  end
@@ -6,7 +6,8 @@ module BinData
6
6
 
7
7
  module Int #:nodoc: all
8
8
  class << self
9
- def define_class(name, nbits, endian, signed)
9
+ def define_class(nbits, endian, signed)
10
+ name = class_name(nbits, endian, signed)
10
11
  unless BinData.const_defined?(name)
11
12
  BinData.module_eval <<-END
12
13
  class #{name} < BinData::BasePrimitive
@@ -18,6 +19,13 @@ module BinData
18
19
  BinData.const_get(name)
19
20
  end
20
21
 
22
+ def class_name(nbits, endian, signed)
23
+ endian_str = (endian == :big) ? "be" : "le"
24
+ base = (signed == :signed) ? "Int" : "Uint"
25
+
26
+ "#{base}#{nbits}#{endian_str}"
27
+ end
28
+
21
29
  def define_methods(int_class, nbits, endian, signed)
22
30
  raise "nbits must be divisible by 8" unless (nbits % 8).zero?
23
31
 
@@ -162,7 +170,7 @@ module BinData
162
170
  if regex =~ name.to_s
163
171
  nbits = $1.to_i
164
172
  if (nbits % 8).zero?
165
- return Int.define_class(name, nbits, *args)
173
+ return Int.define_class(nbits, *args)
166
174
  end
167
175
  end
168
176
  end
@@ -6,10 +6,7 @@ module BinData
6
6
  module IO
7
7
  # Creates a StringIO around +str+.
8
8
  def self.create_string_io(str = "")
9
- if str.respond_to?(:force_encoding)
10
- str = str.dup.force_encoding(Encoding::BINARY)
11
- end
12
- StringIO.new(str)
9
+ StringIO.new(str.dup.force_encoding(Encoding::BINARY))
13
10
  end
14
11
 
15
12
  # Create a new IO Read wrapper around +io+. +io+ must provide #read,
@@ -190,8 +187,8 @@ module BinData
190
187
 
191
188
  # Use #seek and #pos on seekable streams
192
189
  module SeekableStream
193
- # Returns the current offset of the io stream. Offset will be rounded
194
- # up when reading bitfields.
190
+ # Returns the current offset of the io stream. The exact value of
191
+ # the offset when reading bitfields is not defined.
195
192
  def offset
196
193
  raw_io.pos - @initial_pos
197
194
  end
@@ -225,8 +222,8 @@ module BinData
225
222
 
226
223
  # Manually keep track of offset for unseekable streams.
227
224
  module UnSeekableStream
228
- # Returns the current offset of the io stream. Offset will be rounded
229
- # up when reading bitfields.
225
+ # Returns the current offset of the io stream. The exact value of
226
+ # the offset when reading bitfields is not defined.
230
227
  def offset
231
228
  @read_count ||= 0
232
229
  end
@@ -284,8 +281,6 @@ module BinData
284
281
  @wval = 0
285
282
  @wendian = nil
286
283
 
287
- @write_count = 0
288
-
289
284
  @bytes_remaining = nil
290
285
  end
291
286
 
@@ -309,12 +304,6 @@ module BinData
309
304
  end
310
305
  end
311
306
 
312
- # Returns the current offset of the io stream. Offset will be rounded
313
- # up when writing bitfields.
314
- def offset
315
- @write_count + (@wnbits > 0 ? 1 : 0)
316
- end
317
-
318
307
  # Writes the given string of bytes to the io stream.
319
308
  def writebytes(str)
320
309
  flushbits
@@ -402,7 +391,6 @@ module BinData
402
391
  @bytes_remaining -= data.size
403
392
  end
404
393
 
405
- @write_count += data.size
406
394
  @raw_io.write(data)
407
395
  end
408
396
 
@@ -85,7 +85,7 @@ module BinData
85
85
 
86
86
  if obj_parent.has_parameter?(symbol)
87
87
  obj_parent.get_parameter(symbol)
88
- elsif obj_parent.safe_respond_to?(symbol, true)
88
+ elsif obj_parent.safe_respond_to?(symbol)
89
89
  obj_parent.__send__(symbol, *args)
90
90
  else
91
91
  symbol
@@ -118,7 +118,7 @@ module BinData
118
118
  def self.invalid_parameter_names
119
119
  unless defined? @invalid_names
120
120
  all_names = LazyEvaluator.instance_methods(true) + Kernel.methods
121
- allowed_names = ["name", "type", :name, :type] # ruby 1.8 vs 1.9
121
+ allowed_names = [:name, :type]
122
122
  invalid_names = (all_names - allowed_names).uniq
123
123
  @invalid_names = Hash[*invalid_names.collect { |key| [key.to_sym, true] }.flatten]
124
124
  end
@@ -1,10 +1,28 @@
1
1
  require 'bindata/dsl'
2
+ require 'bindata/sanitize'
2
3
  require 'bindata/struct'
3
4
 
4
5
  module BinData
5
6
  # A Record is a declarative wrapper around Struct.
6
7
  #
7
- # See +Struct+ for more info.
8
+ # require 'bindata'
9
+ #
10
+ # class SomeDataType < BinData::Record
11
+ # hide :a
12
+ #
13
+ # int32le :a
14
+ # int16le :b
15
+ # struct :s do
16
+ # int8 :x
17
+ # int8 :y
18
+ # int8 :z
19
+ # end
20
+ # end
21
+ #
22
+ # obj = SomeDataType.new
23
+ # obj.field_names =># [:b, :s]
24
+ # obj.s.field_names =># [:x, :y, :z]
25
+ #
8
26
  class Record < BinData::Struct
9
27
  include DSLMixin
10
28
 
@@ -24,14 +24,6 @@ module BinData
24
24
  end
25
25
  end
26
26
 
27
- def has_parameter?(param)
28
- if @factory
29
- @factory.has_parameter?(param)
30
- else
31
- @obj_params.has_parameter?(param)
32
- end
33
- end
34
-
35
27
  def instantiate(value = nil, parent = nil)
36
28
  @factory ||= @obj_class.new(@obj_params)
37
29
 
@@ -56,10 +48,6 @@ module BinData
56
48
  @name
57
49
  end
58
50
 
59
- def has_parameter?(param)
60
- @prototype.has_parameter?(param)
61
- end
62
-
63
51
  def instantiate(value = nil, parent = nil)
64
52
  @prototype.instantiate(value, parent)
65
53
  end
@@ -95,10 +83,6 @@ module BinData
95
83
  @fields.each(&block)
96
84
  end
97
85
 
98
- def each_with_index(&block)
99
- @fields.each_with_index(&block)
100
- end
101
-
102
86
  def collect(&block)
103
87
  @fields.collect(&block)
104
88
  end
@@ -119,10 +103,6 @@ module BinData
119
103
  @fields.all? { |f| f.name != nil }
120
104
  end
121
105
 
122
- def any_field_has_parameter?(parameter)
123
- @fields.any? { |f| f.has_parameter?(parameter) }
124
- end
125
-
126
106
  def copy_fields(other)
127
107
  @fields.concat(other.fields)
128
108
  end