module MaxCube::Messages::Parser

This module provides methods connected to message parsing only (i.e. direction Cube -> client).

Public Instance Methods

parse_msg_body(body, hash, parser_type) click to toggle source

Parses message body, i.e. at least message type is already decoded. It dynamically calls method corresponding to message and parser type. If message type is not implemented yet, read data is stored as is. It transforms unhandled IOError exceptions (probably raised from {#read}) to {InvalidMessageBody}. @param body [String] message body to be parsed. @param hash [Hash] hash to store parsed data into.

It should already contain contents of message head.
Hash will be modified.

@param parser_type [String] parser type contained in method identifiers. @return [Hash, nil] resulting hash, or nil in case

the message type is not implemented yet.

@raise [InvalidMessageBody] if IOError catched.

# File lib/maxcube/messages/parser.rb, line 52
def parse_msg_body(body, hash, parser_type)
  method_str = "parse_#{parser_type}_#{@msg_type.downcase}"
  if respond_to?(method_str, true)
    return hash.merge!(send(method_str, body))
  end
  hash[:data] = body
  nil
rescue IOError
  raise InvalidMessageBody
    .new(@msg_type, 'unexpected EOF reached')
end
read(count = 0, unpack = false) click to toggle source

This method should be used each time any IO is read, which is very useful for parsing purposes. It contains optional implicit conversion of binary string data of certain length into integers (using {PACK_FORMAT}) or into any other explicit format that String#unpack understands. In addition, it checks whether the read operation succeeded and raises an exception if not (this is useful when parsing a message of a specified format). @param count [Integer] number of bytes to read.

0 causes to read until EOF.

@param unpack [Boolean, String] if true

it does implicit conversion to integer;
if String, the format is passed to String#unpack as is.

@return [String, Integer] read data; its type depends on unpack. @raise [IOError] if reading failed (incl. that nothing was read).

# File lib/maxcube/messages/parser.rb, line 26
def read(count = 0, unpack = false)
  str = if count.zero?
          @io.read
        else
          raise IOError if @io.size - @io.pos < count
          @io.read(count)
        end
  return str unless unpack
  str = "\x00".b + str if count == 3
  unpack = PACK_FORMAT[count] unless unpack.is_a?(String)
  str.unpack1(unpack)
end