class TSparser::Binary

Public Class Methods

from_int(*integers) click to toggle source
# File lib/binary.rb, line 6
def self.from_int(*integers)
  return new(integers.pack("C*"))
end
new(byte_string=nil) click to toggle source

“byte_string” is string encoded as ASCII_8BIT (BINARY).

Calls superclass method
# File lib/binary.rb, line 11
def initialize(byte_string=nil)
  byte_string ||= "".encode(Encoding::ASCII_8BIT)
  if byte_string.encoding != Encoding::ASCII_8BIT
    raise BinaryException.new("byte_string's encoding should be ASCII_8BIT(BINARY) " +
                              "(this is #{byte_string.encoding})")
  end
  super(byte_string)
end

Public Instance Methods

&(byte_integer) click to toggle source
# File lib/binary.rb, line 74
def &(byte_integer)
  if byte_integer < 0x00 || byte_integer > 0xFF
    raise BinaryException.new("Can't apply operator& with integer #{byte_integer}.")
  end
  if self.length != 1
    raise BinaryException.new("Can't apply operator& on bytes #{self}.")
  end
  return Binary.from_int(self.to_i(0) & byte_integer)
end
<=>(integer) click to toggle source

Comparator to Integer

Calls superclass method
# File lib/binary.rb, line 51
def <=>(integer)
  return super unless integer.is_a?(Integer)
  unless self.length == 1
    raise BinaryException.new("Can't compare non-single byte with integer.")
  end
  return self.to_i(0) <=> integer
end
b(byte_index, bit_range=nil) click to toggle source

Return Integer that is converted from bits specified by “bit_range” (arg2) in byte specified by “byte_index” (arg1).

Warning: Bit index is from right to left. So, LSB's position is 0, MSB's is 7

# File lib/binary.rb, line 24
def b(byte_index, bit_range=nil)
  byte_num = self[byte_index].unpack("C")[0]
  return byte_num unless bit_range
  return sub_integer(byte_num, bit_range)
end
dump() click to toggle source
# File lib/binary.rb, line 84
def dump
  bytes = []
  each_byte do |byte|
    bytes << sprintf("%02X", byte)
  end
  return bytes.join(" ")
end
from(start_position) click to toggle source

Generate new Binary instance that is subsequence of self (from specified position to end).

# File lib/binary.rb, line 60
def from(start_position)
  unless start_position < self.length
    raise BinaryException.new("starting point must should be less than length")
  end
  return self[start_position, self.length - start_position]
end
join(*binaries) click to toggle source

Generate new Binary instance that is joined from “self”, “arg1”, “arg2”, … (in order).

# File lib/binary.rb, line 68
def join(*binaries)
  return binaries.inject(self) do |combined, binary|
    Binary.new(combined + binary)
  end
end
sub_integer(integer, bit_range) click to toggle source

Get sub-bit of specified integer.

Example:

binary = Binary.new(something_byte_string)
binary.sub_integer(0b11111100, 1..2) # => 2 (0b10)
# File lib/binary.rb, line 35
def sub_integer(integer, bit_range)
  bit_range = bit_range..bit_range if bit_range.kind_of?(Integer)
  num = 0
  bit_range.reverse_each do |i|
    num = num << 1
    num += integer[i]
  end
  return num
end
to_i(byte_position) click to toggle source

Return Integer that is converted from Byte at specified position.

# File lib/binary.rb, line 46
def to_i(byte_position)
  return self[byte_position].unpack("C")[0]
end

Read methods

↑ top

Public Instance Methods

bit_pointer() click to toggle source
# File lib/binary.rb, line 189
def bit_pointer
  @bit_pointer ||= 0
  return @bit_pointer
end
last_read_byte() click to toggle source
# File lib/binary.rb, line 175
def last_read_byte
  return Binary.new(self[bit_pointer-1])
end
read_bit_as_binary(bitlen) click to toggle source

Read specified length of bits and return as Binary instance. Bit pointer proceed for that length.

Warning: “bitlen” must be integer of multiple of 8, and bit pointer must be pointing start of byte.

# File lib/binary.rb, line 153
def read_bit_as_binary(bitlen)
  unless bit_pointer % 8 == 0
    raise BinaryException.new("Bit pointer must be pointing start of byte. " +
                              "But now pointing #{bit_pointer}.")
  end
  unless bitlen % 8 == 0
    raise BinaryException.new("Arg must be integer of multiple of 8. " +
                              "But you specified #{bitlen}.")
  end
  if self.length - bit_pointer/8 < bitlen/8
    raise BinaryException.new("Rest of self length(#{self.length - bit_pointer/8}byte)" +
                              " is shorter than specified byte length(#{bitlen/8}byte).")
  end
  response = self[bit_pointer/8, bitlen/8]
  bit_pointer_inc(bitlen)
  return response
end
read_bit_as_integer(bitlen) click to toggle source

Read specified length of bits and return as Integer instance. Bit pointer proceed for that length.

# File lib/binary.rb, line 99
def read_bit_as_integer(bitlen)
  if self.length * 8 - bit_pointer < bitlen
    raise BinaryException.new("Rest of self length(#{self.length * 8 - bit_pointer}bit) "+
                              "is shorter than specified bit length(#{bitlen}bit).")
  end
  if bit_pointer % 8 == 0 && bitlen % 8 == 0
    return read_byte_as_integer(bitlen/8)
  else
    response = 0
    bitlen.times do
      response = response << 1
      response += read_one_bit
    end
    return response
  end
end
read_byte_as_binary(bytelen) click to toggle source
# File lib/binary.rb, line 171
def read_byte_as_binary(bytelen)
  return read_bit_as_binary(bytelen*8)
end
read_byte_as_integer(bytelen) click to toggle source

Read specified length of bytes and return as Integer instance. Bit pointer proceed for that length.

# File lib/binary.rb, line 118
def read_byte_as_integer(bytelen)
  unless bit_pointer % 8 == 0
    raise BinaryException.new("Bit pointer must be pointing start of byte. " +
                              "But now pointing #{bit_pointer}.")
  end
  if self.length - bit_pointer/8 < bytelen
    raise BinaryException.new("Rest of self length(#{self.length - bit_pointer/8}byte) " + 
                              "is shorter than specified byte length(#{bytelen}byte).")
  end
  response = 0
  bytelen.times do |i|
    response = response << 8
    response += to_i(bit_pointer/8 + i)
  end
  bit_pointer_inc(bytelen * 8)
  return response
end
read_one_bit() click to toggle source

Read one bit and return as 0 or 1. Bit pointer proceed for one.

# File lib/binary.rb, line 138
def read_one_bit
  unless self.length * 8 - bit_pointer > 0
    raise BinaryException.new("Readable buffer doesn't exist" +
                              "(#{self.length * 8 - bit_pointer}bit exists).")
  end
  response = to_i(bit_pointer/8)[7 - bit_pointer%8]
  bit_pointer_inc(1)
  return response
end
readable?() click to toggle source

Return whether bit pointer reached end or not (true/false).

# File lib/binary.rb, line 180
def readable?
  return bit_pointer < self.length * 8
end
rest_readable_bit_length() click to toggle source

Return length of rest readable bit

# File lib/binary.rb, line 185
def rest_readable_bit_length
  return self.length * 8 - bit_pointer
end

Private Instance Methods

bit_pointer_inc(n) click to toggle source
# File lib/binary.rb, line 196
def bit_pointer_inc(n)
  @bit_pointer ||= 0
  @bit_pointer += n
end