Module: MaxCube::Messages::Parser

Includes:
Handler
Included in:
TCP::Parser, UDP::Parser
Defined in:
lib/maxcube/messages/parser.rb

Overview

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

Constant Summary

Constants included from Handler

Handler::PACK_FORMAT

Constants included from MaxCube::Messages

DAYS_OF_WEEK, DEVICE_MODE, DEVICE_TYPE

Instance Method Summary collapse

Methods included from Handler

#check_data_type, #check_hash, #check_hash_keys, #check_hash_msg_type, #check_hash_values, #check_msg, #check_msg_msg_type, #check_msg_type, #msg_type_hash_keys, #msg_type_hash_opt_keys, #valid_data_type, #valid_hash, #valid_hash_keys, #valid_hash_msg_type, #valid_hash_values, #valid_msg, #valid_msg_msg_type, #valid_msg_type

Instance Method Details

#parse_msg_body(body, hash, parser_type) ⇒ Hash?

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.

Parameters:

  • body (String)

    message body to be parsed.

  • hash (Hash)

    hash to store parsed data into. It should already contain contents of message head. Hash will be modified.

  • parser_type (String)

    parser type contained in method identifiers.

Returns:

  • (Hash, nil)

    resulting hash, or nil in case the message type is not implemented yet.

Raises:



52
53
54
55
56
57
58
59
60
61
62
# 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) ⇒ String, Integer

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 Handler::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).

Parameters:

  • count (Integer) (defaults to: 0)

    number of bytes to read. 0 causes to read until EOF.

  • unpack (Boolean, String) (defaults to: false)

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

Returns:

  • (String, Integer)

    read data; its type depends on unpack.

Raises:

  • (IOError)

    if reading failed (incl. that nothing was read).



26
27
28
29
30
31
32
33
34
35
36
37
# 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