class BinData::DSLMixin::DSLBigAndLittleEndianHandler
:big or :little endian.
This option creates two subclasses, each handling
Handles the :big_and_little endian option.
def ancestor_fields
def ancestor_fields if subclass_of_big_and_little_endian? pparent = @the_class.superclass.superclass ancestor_with_endian = class_with_endian(pparent, @the_class.endian) obj_attribute(ancestor_with_endian, :fields) else nil end end
def class_with_endian(class_name, endian)
def class_with_endian(class_name, endian) RegisteredClasses.lookup(class_name, endian) end
def create_subclasses_with_endian
def create_subclasses_with_endian instance_eval "class ::#{@the_class}Be < ::#{@the_class}; endian :big; end" instance_eval "class ::#{@the_class}Le < ::#{@the_class}; endian :little; end" end
def forward_field_definition(*args, &block)
def forward_field_definition(*args, &block) class_with_endian(@the_class, :big).send(*args, &block) class_with_endian(@the_class, :little).send(*args, &block) end
def initialize(the_class)
def initialize(the_class) @the_class = the_class end
def make_class_abstract
def make_class_abstract @the_class.send(:unregister_self) end
def obj_attribute(obj, attr, default = nil)
def obj_attribute(obj, attr, default = nil) parser = obj.respond_to?(:dsl_parser) ? obj.dsl_parser : nil if parser and parser.respond_to?(attr) parser.send(attr) else default end end
def override_new_in_class
def override_new_in_class saved_class = @the_class endian_classes = { :big => class_with_endian(saved_class, :big), :little => class_with_endian(saved_class, :little), } @the_class.define_singleton_method(:new) do |*args| if self == saved_class value, options, parent = arg_processor.separate_args(self, args) delegate = endian_classes[options[:endian]] return delegate.new(*args) if delegate end super(*args) end end
def prepare_subclasses
def prepare_subclasses create_subclasses_with_endian make_class_abstract override_new_in_class end
def subclass_of_big_and_little_endian?
def subclass_of_big_and_little_endian? parent = @the_class.superclass pparent = parent.superclass obj_attribute(parent, :endian) == :big_and_little and obj_attribute(pparent, :endian) == :big_and_little and [:big, :little].include?(@the_class.endian) end