module MaxCube::Messages::Parser
This module provides methods connected to message parsing only (i.e. direction Cube -> client).
Public Instance Methods
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
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