module Beefcake::Message::Decode

Public Instance Methods

decode(buf, o=self.new) click to toggle source
# File lib/beefcake.rb, line 172
def decode(buf, o=self.new)
  if ! buf.is_a?(Buffer)
    buf = Buffer.new(buf)
  end

  # TODO: test for incomplete buffer
  while buf.length > 0
    fn, wire = buf.read_info

    fld = fields[fn]

    # We don't have a field for with index fn.
    # Ignore this data and move on.
    if fld.nil?
      buf.skip(wire)
      next
    end

    exp = Buffer.wire_for(fld.type)
    if wire != exp
      raise WrongTypeError.new(fld.name, exp, wire)
    end

    if fld.rule == :repeated && fld.opts[:packed]
      len = buf.read_uint64
      tmp = Buffer.new(buf.read(len))
      o[fld.name] ||= []
      while tmp.length > 0
        o[fld.name] << tmp.read(fld.type)
      end
    elsif fld.rule == :repeated
      val = buf.read(fld.type)
      o[fld.name] ||= []
      o[fld.name] << val
    else
      val = buf.read(fld.type)
      o[fld.name] = val
    end
  end

  # Set defaults
  fields.values.each do |f|
    next if o[f.name] == false
    o[f.name] ||= f.opts[:default]
  end

  o.validate!

  o
end
read_delimited(buf, o=self.new) click to toggle source
# File lib/beefcake.rb, line 223
def read_delimited(buf, o=self.new)
  if ! buf.is_a?(Buffer)
    buf = Buffer.new(buf)
  end

  return if buf.length == 0

  n = buf.read_int64
  tmp = Buffer.new(buf.read(n))

  decode(tmp, o)
end