lib/bindata/bits.rb in bindata-1.8.3 vs lib/bindata/bits.rb in bindata-2.0.0
- old
+ new
@@ -4,106 +4,57 @@
# Defines a number of classes that contain a bit based integer.
# The integer is defined by endian and number of bits.
module BitField #:nodoc: all
class << self
- def define_class(name, nbits, endian, signed = :unsigned)
+ def define_class(nbits, endian, signed = :unsigned)
+ name = ((signed == :signed ) ? "Sbit" : "Bit") + nbits.to_s
+ name << "le" if endian == :little
unless BinData.const_defined?(name)
BinData.module_eval <<-END
class #{name} < BinData::BasePrimitive
- BitField.define_methods(self, #{nbits.inspect}, #{endian.inspect}, #{signed.inspect})
+ BitField.define_methods(self, #{nbits}, :#{endian}, :#{signed})
end
END
end
BinData.const_get(name)
end
def define_methods(bit_class, nbits, endian, signed)
bit_class.module_eval <<-END
- #{create_params_code(nbits)}
-
def assign(val)
- #{create_nbits_code(nbits)}
#{create_clamp_code(nbits, signed)}
super(val)
end
def do_write(io)
- #{create_nbits_code(nbits)}
val = _value
- #{create_int2uint_code(nbits, signed)}
+ #{create_int2uint_code(nbits) if signed == :signed}
io.writebits(val, #{nbits}, :#{endian})
end
def do_num_bytes
- #{create_nbits_code(nbits)}
- #{create_do_num_bytes_code(nbits)}
+ #{nbits / 8.0}
end
#---------------
private
-
def read_and_return_value(io)
- #{create_nbits_code(nbits)}
val = io.readbits(#{nbits}, :#{endian})
- #{create_uint2int_code(nbits, signed)}
+ #{create_uint2int_code(nbits) if signed == :signed}
val
end
def sensible_default
0
end
END
end
- def create_params_code(nbits)
- if nbits == :nbits
- "mandatory_parameter :nbits"
- else
- ""
- end
- end
-
- def create_nbits_code(nbits)
- if nbits == :nbits
- "nbits = eval_parameter(:nbits)"
- else
- ""
- end
- end
-
- def create_do_num_bytes_code(nbits)
- if nbits == :nbits
- "nbits / 8.0"
- else
- nbits / 8.0
- end
- end
-
def create_clamp_code(nbits, signed)
- if nbits == :nbits
- create_dynamic_clamp_code(nbits, signed)
- else
- create_fixed_clamp_code(nbits, signed)
- end
- end
-
- def create_dynamic_clamp_code(nbits, signed)
- if signed == :signed
- max = "max = (1 << (nbits - 1)) - 1"
- min = "min = -(max + 1)"
- else
- max = "max = (1 << nbits) - 1"
- min = "min = 0"
- end
-
- "#{max}; #{min}; val = (val < min) ? min : (val > max) ? max : val"
- end
-
- def create_fixed_clamp_code(nbits, signed)
if nbits == 1 and signed == :signed
raise "signed bitfield must have more than one bit"
end
if signed == :signed
@@ -122,53 +73,33 @@
end
"val = #{clamp}"
end
- def create_int2uint_code(nbits, signed)
- if signed != :signed
- ""
- elsif nbits == :nbits
- "val &= (1 << nbits) - 1"
- else
- "val &= #{(1 << nbits) - 1}"
- end
+ def create_int2uint_code(nbits)
+ "val = val & #{(1 << nbits) - 1}"
end
- def create_uint2int_code(nbits, signed)
- if signed != :signed
- ""
- elsif nbits == :nbits
- "val -= (1 << nbits) if (val >= (1 << (nbits - 1)))"
- else
- "val -= #{1 << nbits} if (val >= #{1 << (nbits - 1)})"
- end
+ def create_uint2int_code(nbits)
+ "val = val - #{1 << nbits} if (val >= #{1 << (nbits - 1)})"
end
end
end
- # Create classes for dynamic bitfields
- {
- "Bit" => :big,
- "BitLe" => :little,
- "Sbit" => [:big, :signed],
- "SbitLe" => [:little, :signed],
- }.each_pair { |name, args| BitField.define_class(name, :nbits, *args) }
-
# Create classes on demand
module BitFieldFactory
def const_missing(name)
mappings = {
- /^Bit(\d+)$/ => :big,
- /^Bit(\d+)le$/ => :little,
- /^Sbit(\d+)$/ => [:big, :signed],
+ /^Bit(\d+)$/ => :big,
+ /^Bit(\d+)le$/ => :little,
+ /^Sbit(\d+)$/ => [:big, :signed],
/^Sbit(\d+)le$/ => [:little, :signed]
}
mappings.each_pair do |regex, args|
if regex =~ name.to_s
nbits = $1.to_i
- return BitField.define_class(name, nbits, *args)
+ return BitField.define_class(nbits, *args)
end
end
super(name)
end