module BinData::BitField
def create_clamp_code(nbits)
def create_clamp_code(nbits) min = 0 max = (1 << nbits) - 1 clamp = "val = (val < #{min}) ? #{min} : (val > #{max}) ? #{max} : val" if nbits == 1 # allow single bits to be used as booleans "val = (val == true) ? 1 : (not val) ? 0 : #{clamp}" else clamp end end
def define_class(nbits, endian)
def define_class(nbits, endian) name = "Bit#{nbits}" name += "le" if endian == :little unless BinData.const_defined?(name) BinData.module_eval <<-END class #{name} < BinData::BasePrimitive BitField.define_methods(self, #{nbits}, :#{endian}) end END end BinData.const_get(name) end
def define_methods(bit_class, nbits, endian)
def define_methods(bit_class, nbits, endian) bit_class.module_eval <<-END def assign(val) #{create_clamp_code(nbits)} super(val) end def do_write(io) io.writebits(_value, #{nbits}, :#{endian}) end def do_num_bytes #{nbits / 8.0} end #--------------- private def read_and_return_value(io) io.readbits(#{nbits}, :#{endian}) end def sensible_default 0 end END end