stream.go
changeset 61 16513974d273
parent 59 be6815a9653a
child 62 6e2eea62ccca
--- 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