class BinData::Base

This is the abstract base class for all data objects.

def ==(other) #:nodoc:

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

def =~(other)

Override and delegate =~ as it is defined in Object.
def =~(other)
  snapshot =~ other
end

def abs_offset

distant ancestor.
Returns the offset (in bytes) of this object with respect to its most
def abs_offset
  if @parent
    @parent.abs_offset + @parent.offset_of(self)
  else
    0
  end
end

def arg_processor(name = nil)

The arg processor for this class.
def arg_processor(name = nil)
  if name
    @arg_processor = "#{name}_arg_processor".gsub(/(?:^|_)(.)/) { $1.upcase }.to_sym
  elsif @arg_processor.is_a? Symbol
    @arg_processor = BinData::const_get(@arg_processor).new
  elsif @arg_processor.nil?
    @arg_processor = superclass.arg_processor
  else
    @arg_processor
  end
end

def binary_string(str)

def binary_string(str)
  str.to_s.dup.force_encoding(Encoding::BINARY)
end

def bindata_name

The name of this class as used by Records, Arrays etc.
def bindata_name
  RegisteredClasses.underscore_name(self.name)
end

def clear

Resets the internal state to that of a newly created object.
def clear
  initialize_instance
end

def debug_name

Returns a user friendly name of this object for debugging purposes.
def debug_name
  if @parent
    @parent.debug_name_of(self)
  else
    "obj"
  end
end

def eval_parameter(key, overrides = nil)

Returns nil if +key+ does not refer to any parameter.

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

Returns the result of evaluating the parameter identified by +key+.
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

def extract_args(args)

def extract_args(args)
  self.class.arg_processor.extract_args(self.class, args)
end

def furthest_ancestor

def furthest_ancestor
  if parent.nil?
    self
  else
    an = parent
    an = an.parent while an.parent
    an
  end
end

def get_parameter(key)

You most likely want #eval_parameter.
Use this method if you are sure the parameter is not to be evaluated.
Returns the parameter referenced by +key+.
def get_parameter(key)
  @params[key]
end

def has_parameter?(key)

Returns whether +key+ exists in the +parameters+ hash.
def has_parameter?(key)
  @params.has_parameter?(key)
end

def initialize(*args)


object resides under.
+parent+ is the parent data object (e.g. struct, array, choice) this

reference callable objects (methods or procs).
+parameters+ is a hash containing symbol keys. Some parameters may

+value+ is a value that is +assign+ed immediately after initialization.

Args are optional, but if present, must be in the following order.

Creates a new data object.
def initialize(*args)
  value, @params, @parent = extract_args(args)
  initialize_shared_instance
  initialize_instance
  assign(value) if value
end

def initialize_instance(*args)

def initialize_instance(*args)
  unless args.empty?
    fail "#{caller[0]} remove the call to super in #initialize_instance"
  end
end

def initialize_with_warning(*args)

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

def inspect

Return a human readable representation of this data object.
def inspect
  snapshot.inspect
end

def lazy_evaluator #:nodoc:

:nodoc:
Returns a lazy evaluator for this object.
def lazy_evaluator #:nodoc:
  @lazy ||= LazyEvaluator.new(self)
end

def new(value = nil, parent = nil)

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

Creates a new data object based on this instance.
def new(value = nil, parent = nil)
  obj = clone
  obj.parent = parent if parent
  obj.initialize_instance
  obj.assign(value) if value
  obj
end

def num_bytes

Returns the number of bytes it will take to write this data object.
def num_bytes
  do_num_bytes.ceil
end

def offset

Eventually #rel_offset will be renamed to #offset.
#offset has been renamed to #abs_offset.
def offset
  warn "#offset is deprecated in #{debug_name}. Use #abs_offset instead"
  abs_offset
end

def pretty_print(pp) #:nodoc:

:nodoc:
Work with Ruby's pretty-printer library.
def pretty_print(pp) #:nodoc:
  pp.pp(snapshot)
end

def read(io, *args)

created data object. +args+ will be used when instantiating.
Instantiates this class and reads from +io+, returning the newly
def read(io, *args)
  obj = self.new(*args)
  obj.read(io)
  obj
end

def read(io)

Reads data into this data object.
def read(io)
  io = BinData::IO::Read.new(io) unless BinData::IO::Read === io
  @in_read = true
  clear
  do_read(io)
  @in_read = false
  self
end

def reading? #:nodoc:

:nodoc:
internally by BasePrimitive.
Returns if this object is currently being read. This is used
def reading? #:nodoc:
  furthest_ancestor.in_read
end

def register_subclasses #:nodoc:

:nodoc:
Registers all subclasses of this class for use
def register_subclasses #:nodoc:
  define_singleton_method(:inherited) do |subclass|
    RegisteredClasses.register(subclass.name, subclass)
    register_subclasses
  end
end

def rel_offset

Returns the offset (in bytes) of this object with respect to its parent.
def rel_offset
  if @parent
    @parent.offset_of(self)
  else
    0
  end
end

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

:nodoc:
reinvoke the evaluator so as to avoid infinite evaluation loops.
A version of +respond_to?+ used by the lazy evaluator. It doesn't
def safe_respond_to?(symbol, include_private = false) #:nodoc:
  respond_to?(symbol, include_private)
end

def to_binary_s

Returns the string representation of this data object.
def to_binary_s
  io = BinData::IO.create_string_io
  write(io)
  io.rewind
  io.read
end

def to_hex

Returns the hexadecimal string representation of this data object.
def to_hex
  to_binary_s.unpack('H*')[0]
end

def to_s

Return a string representing this data object.
def to_s
  snapshot.to_s
end

def unregister_self

Call this method if this class is abstract and not to be used.
def unregister_self
  RegisteredClasses.unregister(name)
end

def write(io)

Writes the value for this data object to +io+.
def write(io)
  io = BinData::IO::Write.new(io) unless BinData::IO::Write === io
  do_write(io)
  io.flush
  self
end