class Flt::Bytes
Public Class Methods
pack fixed-width bit-fields as integers into a byte string
# File lib/float-formats/bytes.rb, line 292 def Bytes.from_bitfields(lens,fields,byte_endianness=:little_endian, bits_little_endian=false) i = 0 lens = lens.reverse fields = fields.reverse bits = 0 (0...lens.size).each do |j| i <<= lens[j] i |= fields[j] bits += lens[j] end from_i i,(bits+7)/8,byte_endianness, bits_little_endian end
# File lib/float-formats/bytes.rb, line 313 def Bytes.from_bits(bits,byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) nbits ||= (bits.size+7)/8 from_i bits.to_i, nbits, byte_endianness, bits_little_endian end
generate a byte string from an hex representation
# File lib/float-formats/bytes.rb, line 168 def Bytes.from_hex(hex) Bytes.new [hex.tr(' ','')].pack('H*') end
Convert an integer to a byte string
# File lib/float-formats/bytes.rb, line 265 def Bytes.from_i(i, len=0, byte_endianness=:little_endian, bits_little_endian=false) return nil if i<0 bytes = Bytes.new("") while i>0 b = (i&0xFF) bytes << b i >>= 8 end bytes << 0 while bytes.size<len bytes.reverse_byte_bits! if bits_little_endian bytes.convert_endianness!(:little_endian, byte_endianness) bytes end
# File lib/float-formats/bytes.rb, line 105 def initialize(bytes) case bytes when Bytes @bytes = bytes.to_s when Array @bytes = bytes.pack("C*") else @bytes = bytes.to_str end @bytes.force_encoding("BINARY") if @bytes.respond_to?(:force_encoding) super @bytes end
Public Instance Methods
# File lib/float-formats/bytes.rb, line 149 def +(b) Bytes.new(to_str + b.to_str) end
# File lib/float-formats/bytes.rb, line 128 def [](*params) if params.size == 1 && !params.first.kind_of?(Range) _get_str(params.first).ord # bytes.to_a[params.first] else Bytes.new(_get_str(*params)) end end
# File lib/float-formats/bytes.rb, line 135 def []=(i,v) _set_str i, v.chr(Encoding::BINARY) end
# File lib/float-formats/bytes.rb, line 243 def convert_endianness(from_endianness, to_endianness) dup.convert_endianness!(from_endianness, to_endianness) end
Supported endianness modes for byte strings are:
:little_endian
-
(Intel order): least significant bytes come first.
:big_endian
-
(Network order): most significant bytes come first.
:little_big_endian
or:middle_endian
-
(PDP-11 order): each pair of bytes (16-bit word) has the bytes in little endian order, but the words are stored in big endian order (we assume the number of bytes is even).
Note that the :big_little_endian
order which would logically complete the set is not currently supported as it has no known uses.
# File lib/float-formats/bytes.rb, line 224 def convert_endianness!(from_endianness, to_endianness) if from_endianness!=to_endianness if ([:little_endian,:big_endian]+[from_endianness, to_endianness]).uniq.size==2 # no middle_endian order reverse! else # from or to is middle_endian if [:middle_endian, :little_big_endian].include?(to_endianness) # from little_big_endian convert_endianness!(from_endianness, :big_endian).reverse_byte_pairs! else # from little_big_endian reverse_byte_pairs!.convert_endianness!(:big_endian, to_endianness) end end end self end
# File lib/float-formats/bytes.rb, line 118 def dup Bytes.new @bytes.dup end
# File lib/float-formats/bytes.rb, line 180 def reverse_byte_bits dup.reverse_byte_bits! end
Reverse the order of the bits in each byte.
# File lib/float-formats/bytes.rb, line 174 def reverse_byte_bits! @bytes = @bytes.unpack('b*').pack("B*")[0] __setobj__ @bytes self end
# File lib/float-formats/bytes.rb, line 195 def reverse_byte_nibbles dup.reverse_byte_nibbles! end
Reverse the order of the nibbles in each byte.
# File lib/float-formats/bytes.rb, line 185 def reverse_byte_nibbles! w = "" w.force_encoding("BINARY") if w.respond_to?(:force_encoding) @bytes.each_byte do |b| w << ((b >> 4)|((b&0xF)<<4)) end @bytes = w __setobj__ @bytes self end
# File lib/float-formats/bytes.rb, line 212 def reverse_byte_pairs dup.reverse_byte_pairs! end
reverse the order of bytes in 16-bit words
# File lib/float-formats/bytes.rb, line 200 def reverse_byte_pairs! w = "" w.force_encoding("BINARY") if w.respond_to?(:force_encoding) (0...@bytes.size).step(2) do |i| w << @bytes[i+1] w << @bytes[i] end @bytes = w __setobj__ @bytes self end
# File lib/float-formats/bytes.rb, line 123 def size bytesize end
convert a byte string to separate fixed-width bit-fields as integers
# File lib/float-formats/bytes.rb, line 280 def to_bitfields(lens,byte_endianness=:little_endian, bits_little_endian=false) fields = [] i = to_i(byte_endianness,bits_little_endian) for len in lens mask = (1<<len)-1 fields << (i&mask) i >>= len end fields end
# File lib/float-formats/bytes.rb, line 307 def to_bits(byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) i = to_i(byte_endianness, bits_little_endian) nbits ||= 8*size Bits.from_i(i,nbits) end
return an hex representation of a byte string
# File lib/float-formats/bytes.rb, line 154 def to_hex(sep_bytes=false) hx = @bytes.unpack('H*')[0].upcase if sep_bytes sep = "" (0...hx.size).step(2) do |i| sep << " " unless i==0 sep << hx[i,2] end hx = sep end hx end
Convert a byte string to an integer
# File lib/float-formats/bytes.rb, line 253 def to_i(byte_endianness=:little_endian, bits_little_endian=false) i = 0 bytes = convert_endianness(byte_endianness, :big_endian) bytes = bytes.reverse_byte_bits if bits_little_endian bytes.each_byte do |b| i <<= 8 i |= b end i end