diff -r 6d4f43f7dc19 -r 16513974d273 stream.go --- a/stream.go Sat Jan 07 21:20:23 2012 -0700 +++ b/stream.go Sat Jan 07 22:22:18 2012 -0700 @@ -145,21 +145,15 @@ break } - // If it's a Stanza, we check its "Any" element for a - // namespace that's registered with one of our - // extensions. If so, we need to re-unmarshal into an - // object of the correct type. - if st, ok := obj.(Stanza) ; ok && st.generic() != nil { - name := st.generic().XMLName - ns := name.Space - con := extStanza[ns] - if con != nil { - err = parseExtended(st, con) - if err != nil { - log.Printf("ext unmarshal: %v", - err) - break - } + // If it's a Stanza, we try to unmarshal its innerxml + // into objects of the appropriate respective + // types. This is specified by our extensions. + if st, ok := obj.(Stanza) ; ok { + err = parseExtended(st, extStanza) + if err != nil { + log.Printf("ext unmarshal: %v", + err) + break } } @@ -168,35 +162,35 @@ } } -func parseExtended(st Stanza, con func(*xml.Name) interface{}) os.Error { - name := st.generic().XMLName - nested := con(&name) - +func parseExtended(st Stanza, extStanza map[string] func(*xml.Name) interface{}) os.Error { // Now parse the stanza's innerxml to find the string that we // can unmarshal this nested element from. reader := strings.NewReader(st.innerxml()) p := xml.NewParser(reader) - var start *xml.StartElement for { t, err := p.Token() + if err == os.EOF { + break + } if err != nil { return err } if se, ok := t.(xml.StartElement) ; ok { - if se.Name.Space == name.Space { - start = &se - break + if con, ok := extStanza[se.Name.Space] ; ok { + // Call the indicated constructor. + nested := con(&se.Name) + + // Unmarshal the nested element and + // stuff it back into the stanza. + err := p.Unmarshal(nested, &se) + if err != nil { + return err + } + st.addNested(nested) } } } - // Unmarshal the nested element and stuff it back into the - // stanza. - err := p.Unmarshal(nested, start) - if err != nil { - return err - } - st.setNested(nested) return nil } @@ -594,15 +588,21 @@ if res != "" { bindReq.Resource = &res } - msg := &Iq{Type: "set", Id: <- Id, Nested: &bindReq} + msg := &Iq{Type: "set", Id: <- Id, Nested: []interface{}{bindReq}} f := func(st Stanza) bool { if st.GetType() == "error" { log.Println("Resource binding failed") return false } - bindRepl, ok := st.GetNested().(*bindIq) - if !ok { - log.Printf("bad bind reply: %v", bindRepl) + var bindRepl *bindIq + for _, ele := range(st.GetNested()) { + if b, ok := ele.(*bindIq) ; ok { + bindRepl = b + break + } + } + if bindRepl == nil { + log.Printf("bad bind reply: %v", st) return false } jidStr := bindRepl.Jid