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 arg_extractor

The arg extractor for this class.
def arg_extractor
  BaseArgExtractor
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(the_args)

def extract_args(the_args)
  self.class.arg_extractor.extract(self.class, the_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, parameters, parent = extract_args(args)
  @params = SanitizedParameters.sanitize(parameters, self.class)
  @parent = parent
  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

Returns the offset of this object wrt to its most distant ancestor.
def offset
  if @parent
    @parent.offset + @parent.offset_of(self)
  else
    0
  end
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)

created data object.
Instantiates this class and reads from +io+, returning the newly
def read(io)
  obj = self.new
  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:
  class << self
    define_method(:inherited) do |subclass|
      RegisteredClasses.register(subclass.name, subclass)
      register_subclasses
    end
  end
end

def rel_offset

Returns the offset of this object wrt 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_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