// Scan XML token stream for next element and save into val. // If val == nil, allocate new element based on proto map. // Either way, return val. func next(p *xml.Parser) (xml.Name, interface{}, os.Error) { // Read start element to find out what type we want. se, err := nextStart(p) if err != nil { return xml.Name{}, nil, err } // Put it in an interface and allocate one. var nv interface{} switch se.Name.Space + " " + se.Name.Local { case nsStream + " features": nv = &streamFeatures{} case nsStream + " error": nv = &streamError{} case nsTLS + " starttls": nv = &tlsStartTLS{} case nsTLS + " proceed": nv = &tlsProceed{} case nsTLS + " failure": nv = &tlsFailure{} case nsSASL + " mechanisms": nv = &saslMechanisms{} case nsSASL + " challenge": nv = "" case nsSASL + " response": nv = "" case nsSASL + " abort": nv = &saslAbort{} case nsSASL + " success": nv = &saslSuccess{} case nsSASL + " failure": nv = &saslFailure{} case nsBind + " bind": nv = &bindBind{} case nsClient + " message": nv = &clientMessage{} case nsClient + " presence": nv = &clientPresence{} case nsClient + " iq": nv = &clientIQ{} case nsClient + " error": nv = &clientError{} default: return xml.Name{}, nil, os.ErrorString("unexpected XMPP message " + se.Name.Space + " <" + se.Name.Local + "/>") } // Unmarshal into that storage. if err = p.Unmarshal(nv, &se); err != nil { return xml.Name{}, nil, err } return se.Name, nv, err }