lib/bindata/int.rb in bindata-0.11.0 vs lib/bindata/int.rb in bindata-0.11.1

- old
+ new

@@ -2,53 +2,62 @@ module BinData # Defines a number of classes that contain an integer. The integer # is defined by endian, signedness and number of bytes. - module Integer #:nodoc: all + module Int #:nodoc: all class << self def define_class(nbits, endian, signed) - endian_str = (endian == :big) ? "be" : "le" - if signed == :signed - name = "Int#{nbits}#{endian_str}" - creation_method = "create_int_methods" - else - name = "Uint#{nbits}#{endian_str}" - creation_method = "create_uint_methods" - end + name = class_name(nbits, endian, signed) + return if BinData.const_defined?(name) + int_type = (signed == :signed) ? 'int' : 'uint' + creation_method = "create_#{int_type}_methods" + BinData.module_eval <<-END class #{name} < BinData::BasePrimitive register(self.name, self) - Integer.#{creation_method}(self, #{nbits}, :#{endian.to_s}) + Int.#{creation_method}(self, #{nbits}, :#{endian.to_s}) end END end + def class_name(nbits, endian, signed) + endian_str = (endian == :big) ? "be" : "le" + base = (signed == :signed) ? "Int" : "Uint" + + "#{base}#{nbits}#{endian_str}" + end + def create_uint_methods(int_class, nbits, endian) + raise "nbits must be divisible by 8" unless (nbits % 8).zero? + min = 0 max = (1 << nbits) - 1 clamp = create_clamp_code(min, max) read = create_read_code(nbits, endian) - to_s = create_to_s_code(nbits, endian) + to_binary_s = create_to_binary_s_code(nbits, endian) - define_methods(int_class, nbits / 8, clamp, read, to_s) + define_methods(int_class, nbits / 8, clamp, read, to_binary_s) end def create_int_methods(int_class, nbits, endian) + raise "nbits must be divisible by 8" unless (nbits % 8).zero? + max = (1 << (nbits - 1)) - 1 min = -(max + 1) clamp = create_clamp_code(min, max) read = create_read_code(nbits, endian) - to_s = create_to_s_code(nbits, endian) + to_binary_s = create_to_binary_s_code(nbits, endian) int2uint = create_int2uint_code(nbits) uint2int = create_uint2int_code(nbits) - define_methods(int_class, nbits / 8, clamp, read, to_s, int2uint, uint2int) + define_methods(int_class, nbits / 8, clamp, read, to_binary_s, + int2uint, uint2int) end def create_clamp_code(min, max) "val = (val < #{min}) ? #{min} : (val > #{max}) ? #{max} : val" end @@ -63,12 +72,10 @@ "val = ((val & #{1 << (nbits - 1)}).zero?) ? " + "val & #{mask} : -(((~val) & #{mask}) + 1)" end def create_read_code(nbits, endian) - raise "nbits must be divisible by 8" unless (nbits % 8).zero? - # determine "word" size and unpack directive if (nbits % 32).zero? bytes_per_word = 4 d = (endian == :big) ? 'N' : 'V' elsif (nbits % 16).zero? @@ -95,13 +102,11 @@ assemble_str = parts.join(" + ") "(#{unpack_str}; #{assemble_str})" end - def create_to_s_code(nbits, endian) - raise "nbits must be divisible by 8" unless (nbits % 8).zero? - + def create_to_binary_s_code(nbits, endian) # special case 8bit integers for speed return "val.chr" if nbits == 8 # determine "word" size and pack directive if (nbits % 32).zero? @@ -128,12 +133,12 @@ array_str = "[" + parts.join(", ") + "]" "#{array_str}.pack('#{d * nwords}')" end - def define_methods(int_class, nbytes, clamp, read, to_s, - int2uint = nil, uint2int = nil) + def define_methods(int_class, nbytes, clamp, read, to_binary_s, + int2uint = nil, uint2int = nil) int_class.module_eval <<-END #--------------- private def _assign(val) @@ -150,11 +155,11 @@ end def value_to_binary_string(val) #{clamp} #{int2uint unless int2uint.nil?} - #{to_s} + #{to_binary_s} end def read_and_return_value(io) val = #{read} #{uint2int unless uint2int.nil?} @@ -166,22 +171,22 @@ # Unsigned 1 byte integer. class Uint8 < BinData::BasePrimitive register(self.name, self) - Integer.create_uint_methods(self, 8, :little) + Int.create_uint_methods(self, 8, :little) end # Signed 1 byte integer. class Int8 < BinData::BasePrimitive register(self.name, self) - Integer.create_int_methods(self, 8, :little) + Int.create_int_methods(self, 8, :little) end # Create commonly used integers [8, 16, 32, 64, 128].each do |nbits| - Integer.define_class(nbits, :little, :unsigned) - Integer.define_class(nbits, :little, :signed) - Integer.define_class(nbits, :big, :unsigned) - Integer.define_class(nbits, :big, :signed) + Int.define_class(nbits, :little, :unsigned) + Int.define_class(nbits, :little, :signed) + Int.define_class(nbits, :big, :unsigned) + Int.define_class(nbits, :big, :signed) end end