def initialize *args
opts = args.pop if args.last.is_a? Hash
opts ||= {}
first = args.shift
if first.is_a? ::Class and first.ancestors.include? Protocol::Class
@klass = first
@size = args.shift || 0
@weight = args.shift || 0
@properties = opts
elsif first.is_a? Buffer or first.is_a? String
buf = first
buf = Buffer.new(buf) unless buf.is_a? Buffer
@klass = Protocol.classes[buf.read(:short)]
@weight = buf.read(:short)
@size = buf.read(:longlong)
props = buf.read(:properties, *klass.properties.map{|type,_| type })
@properties = Hash[*klass.properties.map{|_,name| name }.zip(props).reject{|k,v| v.nil? }.flatten]
else
raise ArgumentError, 'Invalid argument'
end
end