class BinData::Base
This is the abstract base class for all data objects.
def ==(other) #:nodoc:
def ==(other) #:nodoc: # double dispatch other == snapshot end
def =~(other)
def =~(other) snapshot =~ other end
def abs_offset
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)
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
def bindata_name RegisteredClasses.underscore_name(self.name) end
def clear
def clear initialize_instance end
def debug_name
def debug_name if @parent @parent.debug_name_of(self) else "obj" end end
def eval_parameter(key, overrides = nil)
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)
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)
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
def inspect snapshot.inspect end
def lazy_evaluator #:nodoc:
Returns a lazy evaluator for this object.
def lazy_evaluator #:nodoc: @lazy ||= LazyEvaluator.new(self) end
def new(value = nil, parent = nil)
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
def num_bytes do_num_bytes.ceil end
def 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:
Work with Ruby's pretty-printer library.
def pretty_print(pp) #:nodoc: pp.pp(snapshot) end
def read(io, *args)
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)
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:
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:
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
def rel_offset if @parent @parent.offset_of(self) else 0 end end
def safe_respond_to?(symbol, include_private = false) #: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
def to_binary_s io = BinData::IO.create_string_io write(io) io.rewind io.read end
def to_hex
def to_hex to_binary_s.unpack('H*')[0] end
def to_s
def to_s snapshot.to_s end
def unregister_self
def unregister_self RegisteredClasses.unregister(name) end
def write(io)
def write(io) io = BinData::IO::Write.new(io) unless BinData::IO::Write === io do_write(io) io.flush self end