module MaxCube::Messages::Serializer

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

Public Instance Methods

serialize(*args, esize: 0, size: 0, count: 0) click to toggle source

Serializes input args into String, with optional implicit conversion from integer into binary string (using {PACK_FORMAT}). In any case, String elements are serialized as they are. @param args [Array<String, Integer>] input arguments. @param 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.

@param 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.

@param 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.

@return [String] serialized args. If conversion was enabled,

it may contain binary data.
# 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_hash_body(hash, serializer_type) click to toggle source

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. @param hash [Hash] hash with message contents to serialize. @param serializer_type [String] serializer type

contained in method identifiers.

@return [String] resulting message string. @raise [InvalidMessageType] if the message type is not implemented yet.

# 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) click to toggle source

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

# 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

Private Instance Methods

serialize_bounds(args, esize: 0, size: 0, count: 0) click to toggle source

Helper method called by {#serialize} that evaluates necessary counts and sizes for purposes of integer elements conversion in loop. @return [[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.
# 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