Module: MaxCube::Messages::Serializer

Includes:
Handler
Included in:
TCP::Serializer, UDP::Serializer
Defined in:
lib/maxcube/messages/serializer.rb

Overview

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

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_part_lengths, #check_msg_type, #decode, #encode, #maybe_check_valid_hash_keys, #maybe_check_valid_msg_type, #msg_type_hash_keys, #msg_type_hash_opt_keys, #msg_type_which_hash_keys, #msg_types, #valid_data_type, #valid_hash, #valid_hash_keys, #valid_hash_msg_type, #valid_hash_values, #valid_msg, #valid_msg_msg_type, #valid_msg_part_lengths, #valid_msg_type

Methods included from MaxCube::Messages

#ary_elem, #ary_elem_id, #conv_args, #day_of_week, #day_of_week_id, #device_mode, #device_mode_id, #device_type, #device_type_id, #to_bool, #to_bools, #to_datetime, #to_datetimes, #to_float, #to_floats, #to_int, #to_ints

Instance Method Details

#serialize(*args, esize: 0, size: 0, count: 0) ⇒ String

Serializes input args into String, with optional implicit conversion from integer into binary string (using Handler::PACK_FORMAT). In any case, String elements are serialized as they are.

Parameters:

  • args (Array<String, Integer>)

    input arguments.

  • esize (Integer)

    output size of binary string of each converted integer element. Nonzero value enables conversion of integers into binary strings. This value is sufficient alone, but it is not suitable in cases when more elements are to be grouped together - esize is in interval (0,1) in this case. Output count (count) is assumed to be the same with input count.

  • size (Integer)

    total output size of binary string of converted integer elements. Nonzero value enables conversion of integers into binary strings. This value is sufficient alone if output count is same with input count.

  • count (Integer)

    output count of converted integer elements. size must be specified. 0 means same count as input count. It is suitable for cases when input and output counts differ.

Returns:

  • (String)

    serialized args. If conversion was enabled, it may contain binary data.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/maxcube/messages/serializer.rb', line 32

def serialize(*args, esize: 0, size: 0, count: 0)
  return args.join if size.zero? && esize.zero?

  count, subcount, subsize = serialize_bounds(args,
                                              esize: esize,
                                              size: size,
                                              count: count)
  str = ''
  args.reverse!
  count.times do
    str << args.pop while args.last.is_a?(String)
    substr = args.pop(subcount).pack(PACK_FORMAT[subsize])
    substr = substr[1..-1] if subsize == 3
    str << substr
  end
  str << args.pop until args.empty?

  str
end

#serialize_bounds(args, esize: 0, size: 0, count: 0) ⇒ [count, subcount, subsize] (private)

Helper method called by #serialize that evaluates necessary counts and sizes for purposes of integer elements conversion in loop.

Returns:

  • ([count, subcount, subsize])

    count is output count of converted elements (0 if args array is empty), subcount is number of elements to be converted together in each step, subsize is output size in bytes to which to convert elements in each step into.



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/maxcube/messages/serializer.rb', line 90

def serialize_bounds(args, esize: 0, size: 0, count: 0)
  icount = args.size - args.count { |a| a.is_a?(String) }
  return 0 if icount.zero?
  if esize.zero?
    count = icount if count.zero?
    subsize = size / count
  else
    size = icount * esize
    count = size / esize
    subsize = esize
  end
  subcount = icount / count

  [count, subcount, subsize]
end

#serialize_hash_body(hash, serializer_type) ⇒ String

Serializes message body, i.e. message head has been already serialized. It dynamically calls method corresponding to message and serializer type. If message type is not implemented yet, it is unclear how to serialize the hash, so an exception is raised.

Parameters:

  • hash (Hash)

    hash with message contents to serialize.

  • serializer_type (String)

    serializer type contained in method identifiers.

Returns:

  • (String)

    resulting message string.

Raises:



70
71
72
73
74
75
76
# File 'lib/maxcube/messages/serializer.rb', line 70

def serialize_hash_body(hash, serializer_type)
  method_str = "serialize_#{serializer_type}_#{@msg_type.downcase}"
  return send(method_str, hash) if respond_to?(method_str, true)
  raise InvalidMessageType
    .new(@msg_type, 'serialization of message type' \
                    ' is not implemented (yet)')
end

#write(*args, esize: 0, size: 0, count: 0) ⇒ Object

It serializes args with #serialize and writes it into internal IO variable.



54
55
56
# File 'lib/maxcube/messages/serializer.rb', line 54

def write(*args, esize: 0, size: 0, count: 0)
  @io.write(serialize(*args, esize: esize, size: size, count: count))
end