class Nstrct::Frame

Constants

FRAME_END
FRAME_OVERHEAD
FRAME_START

Attributes

instruction[RW]

Public Class Methods

available?(buffer) click to toggle source
# File lib/nstrct/frame.rb, line 20
def self.available?(buffer)
  if buffer.size >= 1
    raise StartOfFrameInvalid unless buffer.slice(0).unpack('C')[0] == FRAME_START
    if buffer.size >= 3
      payload_length = buffer.slice(1..2).unpack('S>')[0]
      if buffer.size >= (payload_length + FRAME_OVERHEAD)
        raise EndOfFrameInvalid unless buffer.slice(payload_length + FRAME_OVERHEAD - 1).unpack('C')[0] == FRAME_END
        return true
      end
    end
  end
  false
end
crc32(buffer) click to toggle source
# File lib/nstrct/frame.rb, line 16
def self.crc32(buffer)
  Digest::CRC32.checksum buffer
end
new(instruction) click to toggle source
# File lib/nstrct/frame.rb, line 47
def initialize instruction
  @instruction = instruction
end
parse(buffer) click to toggle source
# File lib/nstrct/frame.rb, line 34
def self.parse buffer
  raise NoFrameAvailable unless self.available?(buffer)
  buffer.slice!(0) # remove start of frame
  length = buffer.slice!(0..1).unpack('S>')[0]
  payload = buffer.slice!(0..length - 1)
  checksum = buffer.slice!(0..3).unpack('L>')[0]
  buffer.slice!(0) # remove end of frame
  raise ChecksumInvalid unless checksum == crc32(payload)
  self.new(Instruction.parse(payload))
end

Public Instance Methods

inspect() click to toggle source

Return a comparable inspection

# File lib/nstrct/frame.rb, line 61
def inspect
  "#<Nstrct::Frame instruction=#{@instruction.inspect}>"
end
pack() click to toggle source
# File lib/nstrct/frame.rb, line 51
def pack
  payload = @instruction.pack
  frame = [FRAME_START].pack('C')
  frame += [payload.size].pack('S>')
  frame += payload
  frame += [Frame.crc32(payload)].pack('L>')
  frame + [FRAME_END].pack('C')
end