def decode(buf, o=self.new)
if ! buf.is_a?(Buffer)
buf = Buffer.new(buf)
end
while buf.length > 0
fn, wire = buf.read_info
fld = fields[fn]
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] ||= []) << val
else
val = buf.read(fld.type)
o[fld.name] = val
end
end
fields.values.each do |f|
next if o[f.name] == false
o[f.name] ||= f.opts[:default]
end
o.validate!
o
end