bindata 1.2.1 → 1.2.2

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.

data/ChangeLog CHANGED
@@ -1,5 +1,13 @@
1
1
  = BinData Changelog
2
2
 
3
+ == Version 1.2.2 (2010-12-14)
4
+
5
+ * Added Base.bindata_name method.
6
+ * Removed Base#done_read to reduce memory usage and cpu usage.
7
+ * Derived classes should now use do_read et al, instead of _do_read.
8
+ * Added predefinition of record fields to improve speed.
9
+ * Made compatible with ruby 1.9.2. Thanks to Andrew Watts.
10
+
3
11
  == Version 1.2.1 (2010-07-20)
4
12
 
5
13
  * Updated specs to be compatible with ruby 1.9.1
data/Rakefile CHANGED
@@ -10,7 +10,8 @@ PKG_FILES = FileList[
10
10
  "{examples,spec,lib}/**/*.rb",
11
11
  "tasks/**/*.rake",
12
12
  "setup.rb",
13
- "manual.haml"
13
+ "manual.haml",
14
+ "manual.md"
14
15
  ]
15
16
 
16
17
  task :default => :spec
data/lib/bindata.rb CHANGED
@@ -30,5 +30,5 @@ require 'bindata/deprecated'
30
30
  #
31
31
  # Copyright (c) 2007 - 2010 Dion Mendel.
32
32
  module BinData
33
- VERSION = "1.2.1"
33
+ VERSION = "1.2.2"
34
34
  end
data/lib/bindata/array.rb CHANGED
@@ -93,6 +93,16 @@ module BinData
93
93
  @element_list = nil
94
94
  end
95
95
 
96
+ def assign(array)
97
+ raise ArgumentError, "can't set a nil value for #{debug_name}" if array.nil?
98
+
99
+ @element_list = to_storage_formats(array.to_ary)
100
+ end
101
+
102
+ def snapshot
103
+ elements.collect { |el| el.snapshot }
104
+ end
105
+
96
106
  def find_index(obj)
97
107
  elements.index(obj)
98
108
  end
@@ -224,6 +234,22 @@ module BinData
224
234
  child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor
225
235
  end
226
236
 
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
+ def do_write(io) #:nodoc:
246
+ elements.each { |el| el.do_write(io) }
247
+ end
248
+
249
+ def do_num_bytes #:nodoc:
250
+ sum_num_bytes_for_all_elements.ceil
251
+ end
252
+
227
253
  #---------------
228
254
  private
229
255
 
@@ -244,14 +270,6 @@ module BinData
244
270
  element
245
271
  end
246
272
 
247
- def _do_read(io)
248
- if has_parameter?(:initial_length)
249
- elements.each { |el| el.do_read(io) }
250
- elsif has_parameter?(:read_until)
251
- read_until(io)
252
- end
253
- end
254
-
255
273
  def read_until(io)
256
274
  if get_parameter(:read_until) == :eof
257
275
  read_until_eof(io)
@@ -282,28 +300,6 @@ module BinData
282
300
  end
283
301
  end
284
302
 
285
- def _done_read
286
- elements.each { |el| el.done_read }
287
- end
288
-
289
- def _do_write(io)
290
- elements.each { |el| el.do_write(io) }
291
- end
292
-
293
- def _do_num_bytes
294
- sum_num_bytes_for_all_elements.ceil
295
- end
296
-
297
- def _assign(array)
298
- raise ArgumentError, "can't set a nil value for #{debug_name}" if array.nil?
299
-
300
- @element_list = to_storage_formats(array.to_ary)
301
- end
302
-
303
- def _snapshot
304
- elements.collect { |el| el.snapshot }
305
- end
306
-
307
303
  def elements
308
304
  if @element_list.nil?
309
305
  @element_list = []
data/lib/bindata/base.rb CHANGED
@@ -43,6 +43,11 @@ module BinData
43
43
  data
44
44
  end
45
45
 
46
+ # The name of this class as used by Records, Arrays etc.
47
+ def bindata_name
48
+ RegisteredClasses.underscore_name(self.name)
49
+ end
50
+
46
51
  # Registers this class for use.
47
52
  def register_self
48
53
  register_class(self)
@@ -74,6 +79,8 @@ module BinData
74
79
  def initialize(parameters = {}, parent = nil)
75
80
  @params = Sanitizer.sanitize(parameters, self.class)
76
81
  @parent = parent
82
+
83
+ prepare_for_read_with_offset
77
84
  end
78
85
 
79
86
  attr_reader :parent
@@ -104,21 +111,24 @@ module BinData
104
111
  def read(io)
105
112
  io = BinData::IO.new(io) unless BinData::IO === io
106
113
 
114
+ @in_read = true
115
+ clear
107
116
  do_read(io)
108
- done_read
117
+ @in_read = false
118
+
109
119
  self
110
120
  end
111
121
 
112
- def do_read(io) #:nodoc:
113
- check_or_adjust_offset(io)
114
- clear
115
- _do_read(io)
116
- end
122
+ #:nodoc:
123
+ attr_reader :in_read
124
+ protected :in_read
117
125
 
118
- def done_read #:nodoc:
119
- _done_read
126
+ # Returns if this object is currently being read. This is used
127
+ # internally by BasePrimitive.
128
+ def reading? #:nodoc:
129
+ furthest_ancestor.in_read
120
130
  end
121
- protected :do_read, :done_read
131
+ protected :reading?
122
132
 
123
133
  # Writes the value for this data object to +io+.
124
134
  def write(io)
@@ -129,32 +139,11 @@ module BinData
129
139
  self
130
140
  end
131
141
 
132
- def do_write(io) #:nodoc:
133
- _do_write(io)
134
- end
135
- protected :do_write
136
-
137
142
  # Returns the number of bytes it will take to write this data object.
138
143
  def num_bytes
139
144
  do_num_bytes.ceil
140
145
  end
141
146
 
142
- def do_num_bytes #:nodoc:
143
- _do_num_bytes
144
- end
145
- protected :do_num_bytes
146
-
147
- # Assigns the value of +val+ to this data object. Note that +val+ will
148
- # always be deep copied to ensure no aliasing problems can occur.
149
- def assign(val)
150
- _assign(val)
151
- end
152
-
153
- # Returns a snapshot of this data object.
154
- def snapshot
155
- _snapshot
156
- end
157
-
158
147
  # Returns the string representation of this data object.
159
148
  def to_binary_s
160
149
  io = BinData::IO.create_string_io
@@ -213,6 +202,31 @@ module BinData
213
202
  #---------------
214
203
  private
215
204
 
205
+ def furthest_ancestor
206
+ if parent.nil?
207
+ self
208
+ else
209
+ an = parent
210
+ an = an.parent while an.parent
211
+ an
212
+ end
213
+ end
214
+
215
+ def prepare_for_read_with_offset
216
+ if has_parameter?(:check_offset) or has_parameter?(:adjust_offset)
217
+ class << self
218
+ alias_method :do_read_without_offset, :do_read
219
+ alias_method :do_read, :do_read_with_offset
220
+ public :do_read # Ruby 1.9.2 bug. Should be protected
221
+ end
222
+ end
223
+ end
224
+
225
+ def do_read_with_offset(io) #:nodoc:
226
+ check_or_adjust_offset(io)
227
+ do_read_without_offset(io)
228
+ end
229
+
216
230
  def check_or_adjust_offset(io)
217
231
  if has_parameter?(:check_offset)
218
232
  check_offset(io)
@@ -268,6 +282,17 @@ module BinData
268
282
  raise NotImplementedError
269
283
  end
270
284
 
285
+ # Assigns the value of +val+ to this data object. Note that +val+ will
286
+ # always be deep copied to ensure no aliasing problems can occur.
287
+ def assign(val)
288
+ raise NotImplementedError
289
+ end
290
+
291
+ # Returns a snapshot of this data object.
292
+ def snapshot
293
+ raise NotImplementedError
294
+ end
295
+
271
296
  # Returns the debug name of +child+. This only needs to be implemented
272
297
  # by objects that contain child objects.
273
298
  def debug_name_of(child) #:nodoc:
@@ -281,39 +306,23 @@ module BinData
281
306
  end
282
307
 
283
308
  # Reads the data for this data object from +io+.
284
- def _do_read(io)
285
- raise NotImplementedError
286
- end
287
-
288
- # Trigger function that is called after #do_read.
289
- def _done_read
309
+ def do_read(io) #:nodoc:
290
310
  raise NotImplementedError
291
311
  end
292
312
 
293
313
  # Writes the value for this data to +io+.
294
- def _do_write(io)
314
+ def do_write(io) #:nodoc:
295
315
  raise NotImplementedError
296
316
  end
297
317
 
298
318
  # Returns the number of bytes it will take to write this data.
299
- def _do_num_bytes
300
- raise NotImplementedError
301
- end
302
-
303
- # Assigns the value of +val+ to this data object. Note that +val+ will
304
- # always be deep copied to ensure no aliasing problems can occur.
305
- def _assign(val)
306
- raise NotImplementedError
307
- end
308
-
309
- # Returns a snapshot of this data object.
310
- def _snapshot
319
+ def do_num_bytes #:nodoc:
311
320
  raise NotImplementedError
312
321
  end
313
322
 
314
323
  # Set visibility requirements of methods to implement
315
- public :clear, :clear?, :debug_name_of, :offset_of
316
- private :_do_read, :_done_read, :_do_write, :_do_num_bytes, :_assign, :_snapshot
324
+ public :clear, :clear?, :assign, :snapshot, :debug_name_of, :offset_of
325
+ protected :do_read, :do_write, :do_num_bytes
317
326
 
318
327
  # End To be implemented by subclasses
319
328
  ###########################################################################
@@ -36,8 +36,7 @@ module BinData
36
36
  # either #read or explicitly set with #value=.
37
37
  # [<tt>:value</tt>] The object will always have this value.
38
38
  # Calls to #value= are ignored when
39
- # using this param. In the interval between
40
- # calls to #do_read and #done_read, #value
39
+ # using this param. While reading, #value
41
40
  # will return the value of the data read from the
42
41
  # IO, not the result of the <tt>:value</tt> param.
43
42
  # [<tt>:check_value</tt>] Raise an error unless the value read in meets
@@ -54,19 +53,35 @@ module BinData
54
53
  def initialize(parameters = {}, parent = nil)
55
54
  super
56
55
 
57
- @value = nil
58
- @in_read = false
56
+ @value = nil
59
57
  end
60
58
 
61
59
  def clear #:nodoc:
62
60
  @value = nil
63
- @in_read = false
64
61
  end
65
62
 
66
63
  def clear? #:nodoc:
67
64
  @value.nil?
68
65
  end
69
66
 
67
+ def assign(val)
68
+ raise ArgumentError, "can't set a nil value for #{debug_name}" if val.nil?
69
+
70
+ unless has_parameter?(:value)
71
+ raw_val = val.respond_to?(:snapshot) ? val.snapshot : val
72
+ @value = begin
73
+ raw_val.dup
74
+ rescue TypeError
75
+ # can't dup Fixnums
76
+ raw_val
77
+ end
78
+ end
79
+ end
80
+
81
+ def snapshot
82
+ _value
83
+ end
84
+
70
85
  def value
71
86
  # TODO: warn "#value is deprecated, use #snapshot instead"
72
87
  snapshot
@@ -98,11 +113,7 @@ module BinData
98
113
  snapshot.hash
99
114
  end
100
115
 
101
- #---------------
102
- private
103
-
104
- def _do_read(io)
105
- @in_read = true
116
+ def do_read(io) #:nodoc:
106
117
  @value = read_and_return_value(io)
107
118
 
108
119
  trace_value
@@ -112,6 +123,17 @@ module BinData
112
123
  end
113
124
  end
114
125
 
126
+ def do_write(io) #:nodoc:
127
+ io.writebytes(value_to_binary_string(_value))
128
+ end
129
+
130
+ def do_num_bytes #:nodoc:
131
+ value_to_binary_string(_value).length
132
+ end
133
+
134
+ #---------------
135
+ private
136
+
115
137
  def trace_value
116
138
  BinData::trace_message do |tracer|
117
139
  value_string = _value.inspect
@@ -131,50 +153,19 @@ module BinData
131
153
  end
132
154
  end
133
155
 
134
- def _done_read
135
- @in_read = false
136
- end
137
-
138
- def _do_write(io)
139
- raise "can't write whilst reading #{debug_name}" if @in_read
140
- io.writebytes(value_to_binary_string(_value))
141
- end
142
-
143
- def _do_num_bytes
144
- value_to_binary_string(_value).length
145
- end
146
-
147
- def _assign(val)
148
- raise ArgumentError, "can't set a nil value for #{debug_name}" if val.nil?
149
-
150
- unless has_parameter?(:value)
151
- raw_val = val.respond_to?(:snapshot) ? val.snapshot : val
152
- @value = begin
153
- raw_val.dup
154
- rescue TypeError
155
- # can't dup Fixnums
156
- raw_val
157
- end
158
- end
159
- end
160
-
161
- def _snapshot
162
- _value
163
- end
164
-
165
156
  # The unmodified value of this data object. Note that #value calls this
166
157
  # method. This indirection is so that #value can be overridden in
167
158
  # subclasses to modify the value.
168
159
  def _value
169
160
  # Table of possible preconditions and expected outcome
170
- # 1. :value and !in_read -> :value
171
- # 2. :value and in_read -> @value
161
+ # 1. :value and !reading? -> :value
162
+ # 2. :value and reading? -> @value
172
163
  # 3. :initial_value and clear? -> :initial_value
173
164
  # 4. :initial_value and !clear? -> @value
174
165
  # 5. clear? -> sensible_default
175
166
  # 6. !clear? -> @value
176
167
 
177
- if not @in_read and has_parameter?(:value)
168
+ if has_parameter?(:value) and not reading?
178
169
  # rule 1 above
179
170
  eval_parameter(:value)
180
171
  else
data/lib/bindata/bits.rb CHANGED
@@ -23,23 +23,22 @@ module BinData
23
23
 
24
24
  def define_methods(bit_class, nbits, endian)
25
25
  bit_class.module_eval <<-END
26
- #---------------
27
- private
28
-
29
- def _assign(val)
26
+ def assign(val)
30
27
  #{create_clamp_code(nbits)}
31
28
  super(val)
32
29
  end
33
30
 
34
- def _do_write(io)
35
- raise "can't write whilst reading \#{debug_name}" if @in_read
31
+ def do_write(io)
36
32
  io.writebits(_value, #{nbits}, :#{endian})
37
33
  end
38
34
 
39
- def _do_num_bytes
35
+ def do_num_bytes
40
36
  #{nbits / 8.0}
41
37
  end
42
38
 
39
+ #---------------
40
+ private
41
+
43
42
  def read_and_return_value(io)
44
43
  io.readbits(#{nbits}, :#{endian})
45
44
  end