class Flt::Bytes

Public Class Methods

from_bitfields(lens,fields,byte_endianness=:little_endian, bits_little_endian=false) click to toggle source

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
from_bits(bits,byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) click to toggle source
# 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
from_hex(hex) click to toggle source

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
from_i(i, len=0, byte_endianness=:little_endian, bits_little_endian=false) click to toggle source

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
new(bytes) click to toggle source
Calls superclass method
# 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

+(b) click to toggle source
# File lib/float-formats/bytes.rb, line 149
def +(b)
  Bytes.new(to_str + b.to_str)
end
[](*params) click to toggle source
# 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
Also aliased as: _get_str, _get_str
[]=(i,v) click to toggle source
# File lib/float-formats/bytes.rb, line 135
def []=(i,v)
  _set_str i, v.chr(Encoding::BINARY)
end
Also aliased as: _set_str
_get_str(*params)
Alias for: []
_set_str(i,v)
Alias for: []=
convert_endianness(from_endianness, to_endianness) click to toggle source
# File lib/float-formats/bytes.rb, line 243
def convert_endianness(from_endianness, to_endianness)
  dup.convert_endianness!(from_endianness, to_endianness)
end
convert_endianness!(from_endianness, to_endianness) click to toggle source

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
dup() click to toggle source
# File lib/float-formats/bytes.rb, line 118
def dup
  Bytes.new @bytes.dup
end
reverse_byte_bits() click to toggle source
# File lib/float-formats/bytes.rb, line 180
def reverse_byte_bits
  dup.reverse_byte_bits!
end
reverse_byte_bits!() click to toggle source

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
reverse_byte_nibbles() click to toggle source
# File lib/float-formats/bytes.rb, line 195
def reverse_byte_nibbles
  dup.reverse_byte_nibbles!
end
reverse_byte_nibbles!() click to toggle source

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
reverse_byte_pairs() click to toggle source
# File lib/float-formats/bytes.rb, line 212
def reverse_byte_pairs
  dup.reverse_byte_pairs!
end
reverse_byte_pairs!() click to toggle source

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
size() click to toggle source
# File lib/float-formats/bytes.rb, line 123
def size
  bytesize
end
to_bitfields(lens,byte_endianness=:little_endian, bits_little_endian=false) click to toggle source

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
to_bits(byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) click to toggle source
# 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
to_hex(sep_bytes=false) click to toggle source

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
to_i(byte_endianness=:little_endian, bits_little_endian=false) click to toggle source

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