Class: BinData::Base

Inherits:
Object
  • Object
show all
Includes:
AcceptedParametersMixin, CheckOrAdjustOffsetMixin
Defined in:
lib/bindata/base.rb,
lib/bindata/struct.rb,
lib/bindata/deprecated.rb

Overview

This is the abstract base class for all data objects.

Direct Known Subclasses

Array, BasePrimitive, Choice, ResumeByteAlignment, Struct

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CheckOrAdjustOffsetMixin

#do_read_with_adjust_offset, #do_read_with_check_offset, included

Methods included from AcceptedParametersMixin

included

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



127
128
129
# File 'lib/bindata/base.rb', line 127

def parent
  @parent
end

Class Method Details

.arg_extractorObject

The arg extractor for this class.



55
56
57
# File 'lib/bindata/base.rb', line 55

def arg_extractor
  BaseArgExtractor
end

.bindata_nameObject

The name of this class as used by Records, Arrays etc.



60
61
62
# File 'lib/bindata/base.rb', line 60

def bindata_name
  RegisteredClasses.underscore_name(self.name)
end

.read(io) ⇒ Object

Instantiates this class and reads from io, returning the newly created data object.



48
49
50
51
52
# File 'lib/bindata/base.rb', line 48

def read(io)
  obj = self.new
  obj.read(io)
  obj
end

.register_subclassesObject

Registers all subclasses of this class for use



70
71
72
73
74
75
76
77
# File 'lib/bindata/base.rb', line 70

def register_subclasses #:nodoc:
  class << self
    define_method(:inherited) do |subclass|
      RegisteredClasses.register(subclass.name, subclass)
      register_subclasses
    end
  end
end

.unregister_selfObject

Call this method if this class is abstract and not to be used.



65
66
67
# File 'lib/bindata/base.rb', line 65

def unregister_self
  RegisteredClasses.unregister(name)
end

Instance Method Details

#==(other) ⇒ Object

:nodoc:



267
268
269
270
# File 'lib/bindata/base.rb', line 267

def ==(other) #:nodoc:
  # double dispatch
  other == snapshot
end

#=~(other) ⇒ Object

Override and delegate =~ as it is defined in Object.



236
237
238
# File 'lib/bindata/base.rb', line 236

def =~(other)
  snapshot =~ other
end

#assign(val) ⇒ Object

Assigns the value of val to this data object. Note that val must always be deep copied to ensure no aliasing problems can occur.

Raises:

  • (NotImplementedError)


344
345
346
# File 'lib/bindata/base.rb', line 344

def assign(val)
  raise NotImplementedError
end

#clearObject

Resets the internal state to that of a newly created object.

Raises:

  • (NotImplementedError)


333
334
335
# File 'lib/bindata/base.rb', line 333

def clear
  raise NotImplementedError
end

#clear?Boolean

Returns true if the object has not been changed since creation.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


338
339
340
# File 'lib/bindata/base.rb', line 338

def clear?
  raise NotImplementedError
end

#debug_nameObject

Returns a user friendly name of this object for debugging purposes.



241
242
243
244
245
246
247
# File 'lib/bindata/base.rb', line 241

def debug_name
  if @parent
    @parent.debug_name_of(self)
  else
    "obj"
  end
end

#debug_name_of(child) ⇒ Object

Returns the debug name of child. This only needs to be implemented by objects that contain child objects.



355
356
357
# File 'lib/bindata/base.rb', line 355

def debug_name_of(child) #:nodoc:
  debug_name
end

#eval_parameter(key, overrides = nil) ⇒ Object

Returns the result of evaluating the parameter identified by key.

overrides is an optional parameters like hash that allow the parameters given at object construction to be overridden.

Returns nil if key does not refer to any parameter.



149
150
151
152
153
154
155
156
# File 'lib/bindata/base.rb', line 149

def eval_parameter(key, overrides = nil)
  value = get_parameter(key)
  if value.is_a?(Symbol) or value.respond_to?(:arity)
    lazy_evaluator.lazy_eval(value, overrides)
  else
    value
  end
end

#get_parameter(key) ⇒ Object

Returns the parameter referenced by key. Use this method if you are sure the parameter is not to be evaluated. You most likely want #eval_parameter.



166
167
168
# File 'lib/bindata/base.rb', line 166

def get_parameter(key)
  @params[key]
end

#has_parameter?(key) ⇒ Boolean

Returns whether key exists in the parameters hash.

Returns:

  • (Boolean)


171
172
173
# File 'lib/bindata/base.rb', line 171

def has_parameter?(key)
  @params.has_parameter?(key)
end

#initialize_instance(*args) ⇒ Object

Initializes the state of the object. All instance variables that are used by the object must be initialized here.



320
321
# File 'lib/bindata/base.rb', line 320

def initialize_instance
end

#initialize_with_warning(*args) ⇒ Object Also known as: initialize



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/bindata/deprecated.rb', line 30

def initialize_with_warning(*args)
  owner = method(:initialize).owner
  if owner != BinData::Base
    msg = "Don't override #initialize on #{owner}."
    if %w(BinData::Base BinData::BasePrimitive).include? self.class.superclass.name
      msg += "\nrename #initialize to #initialize_instance."
    end
    fail msg
  end
  initialize_without_warning(*args)
end

#inspectObject

Return a human readable representation of this data object.



221
222
223
# File 'lib/bindata/base.rb', line 221

def inspect
  snapshot.inspect
end

#lazy_evaluatorObject

Returns a lazy evaluator for this object.



159
160
161
# File 'lib/bindata/base.rb', line 159

def lazy_evaluator #:nodoc:
  @lazy ||= LazyEvaluator.new(self)
end

#new(value = nil, parent = nil) ⇒ Object

Creates a new data object based on this instance.

All parameters will be be duplicated. Use this method when creating multiple objects with the same parameters.



134
135
136
137
138
139
140
141
# File 'lib/bindata/base.rb', line 134

def new(value = nil, parent = nil)
  obj = clone
  obj.parent = parent if parent
  obj.initialize_instance
  obj.assign(value) if value

  obj
end

#num_bytesObject

Returns the number of bytes it will take to write this data object.



208
209
210
# File 'lib/bindata/base.rb', line 208

def num_bytes
  do_num_bytes.ceil
end

#offsetObject

Returns the offset of this object wrt to its most distant ancestor.



250
251
252
253
254
255
256
# File 'lib/bindata/base.rb', line 250

def offset
  if @parent
    @parent.offset + @parent.offset_of(self)
  else
    0
  end
end

#offset_of(child) ⇒ Object

Returns the offset of child. This only needs to be implemented by objects that contain child objects.



361
362
363
# File 'lib/bindata/base.rb', line 361

def offset_of(child) #:nodoc:
  0
end

#pretty_print(pp) ⇒ Object

Work with Ruby’s pretty-printer library.



231
232
233
# File 'lib/bindata/base.rb', line 231

def pretty_print(pp) #:nodoc:
  pp.pp(snapshot)
end

#read(io) ⇒ Object

Reads data into this data object.



176
177
178
179
180
181
182
183
184
185
# File 'lib/bindata/base.rb', line 176

def read(io)
  io = BinData::IO.new(io) unless BinData::IO === io

  @in_read = true
  clear
  do_read(io)
  @in_read = false

  self
end

#rel_offsetObject

Returns the offset of this object wrt to its parent.



259
260
261
262
263
264
265
# File 'lib/bindata/base.rb', line 259

def rel_offset
  if @parent
    @parent.offset_of(self)
  else
    0
  end
end

#safe_respond_to?(symbol, include_private = false) ⇒ Boolean

A version of respond_to? used by the lazy evaluator. It doesn’t reinvoke the evaluator so as to avoid infinite evaluation loops.

Returns:

  • (Boolean)


274
275
276
# File 'lib/bindata/base.rb', line 274

def safe_respond_to?(symbol, include_private = false) #:nodoc:
  respond_to?(symbol, include_private)
end

#snapshotObject

Returns a snapshot of this data object.

Raises:

  • (NotImplementedError)


349
350
351
# File 'lib/bindata/base.rb', line 349

def snapshot
  raise NotImplementedError
end

#to_binary_sObject

Returns the string representation of this data object.



213
214
215
216
217
218
# File 'lib/bindata/base.rb', line 213

def to_binary_s
  io = BinData::IO.create_string_io
  write(io)
  io.rewind
  io.read
end

#to_sObject

Return a string representing this data object.



226
227
228
# File 'lib/bindata/base.rb', line 226

def to_s
  snapshot.to_s
end

#write(io) ⇒ Object

Writes the value for this data object to io.



199
200
201
202
203
204
205
# File 'lib/bindata/base.rb', line 199

def write(io)
  io = BinData::IO.new(io) unless BinData::IO === io

  do_write(io)
  io.flush
  self
end