module MQTTPipe::Packer

The packer module is used to pack/unpack classes that supports it.

Public Instance Methods

[](*values)
Alias for: pack
pack(*values) click to toggle source

Packs the arguments acording to their type.

An ArgumentError is raised if any given class does not support packing.

# File lib/mqtt_pipe/packer.rb, line 55
def pack *values
  values.map{|value| value.to_packed }.join
rescue NoMethodError
  raise ArgumentError, 'Unknown input format'
end
Also aliased as: []
read_packed_bytes(n = 1, from:, as: 'C') click to toggle source

A simple helper method to read a given number of bytes from IO object and format them as anything supported by Array#unpack.

# File lib/mqtt_pipe/packer.rb, line 90
def read_packed_bytes n = 1, from:, as: 'C'
  raw = from.read(n)
  raise FormatError if raw.nil? or raw.length != n
  
  raw.unpack(as).first
end
supports?(type)
Alias for: supports_type?
supports_type?(type) click to toggle source

Checks whether a class or object is supported by the packer. For arrays each item is checked recursivly

# File lib/mqtt_pipe/packer.rb, line 33
def supports_type? type
  if type.is_a? Class
    type.to_packed
  elsif type.is_a? Array
    return type.detect{|obj| not supports_type? obj }.nil?
  else
    type.class.to_packed
  end
  return true
rescue NoMethodError
  return false
end
Also aliased as: supports?
unpack(raw, limit: nil) click to toggle source

Unpacks a serialized object and returns an array of the original values.

# File lib/mqtt_pipe/packer.rb, line 68
def unpack raw, limit: nil
  raw = ::StringIO.new raw unless raw.respond_to? :read
  result = []
  
  # Either loop infinately or the number of times
  # specified by limit
  
  (limit.nil? ? loop : limit.times).each do
    result << unpack_single(raw)
  end
  
  return result
rescue EndOfPacket
  return result
end

Private Instance Methods

unpack_single(raw) click to toggle source
# File lib/mqtt_pipe/packer.rb, line 100
def unpack_single raw
  code = raw.read 1
  raise EndOfPacket if code.nil?
  
  type = code.unpack(?C).first
  Types::Type.lookup(type).from_packed type, raw
end