xmpp.go
changeset 36 9fe022261dcc
parent 34 7b1f924c75e2
child 38 2839fece923e
--- a/xmpp.go	Fri Dec 30 18:25:08 2011 -0700
+++ b/xmpp.go	Fri Dec 30 21:49:00 2011 -0700
@@ -83,7 +83,8 @@
 // has completed. The negotiation will occur asynchronously, and any
 // send operation to Client.Out will block until negotiation (resource
 // binding) is complete.
-func NewClient(jid *JID, password string) (*Client, os.Error) {
+func NewClient(jid *JID, password string,
+	extStanza map[string] func(*xml.Name) ExtendedStanza) (*Client, os.Error) {
 	// Resolve the domain in the JID.
 	_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain)
 	if err != nil {
@@ -120,6 +121,11 @@
 	idCh := make(chan string)
 	cl.Id = idCh
 
+	if extStanza == nil {
+		extStanza = make(map[string] func(*xml.Name) ExtendedStanza)
+	}
+	extStanza[NsRoster] = rosterStanza
+
 	// Start the unique id generator.
 	go makeIds(idCh)
 
@@ -127,7 +133,7 @@
 	tlsr, tlsw := cl.startTransport()
 
 	// Start the reader and writers that convert to and from XML.
-	xmlIn := startXmlReader(tlsr)
+	xmlIn := startXmlReader(tlsr, extStanza)
 	cl.xmlOut = startXmlWriter(tlsw)
 
 	// Start the XMPP stream handler which filters stream-level
@@ -158,9 +164,10 @@
 	return inr, outw
 }
 
-func startXmlReader(r io.Reader) <-chan interface{} {
+func startXmlReader(r io.Reader,
+	extStanza map[string] func(*xml.Name) ExtendedStanza) <-chan interface{} {
 	ch := make(chan interface{})
-	go readXml(r, ch)
+	go readXml(r, ch, extStanza)
 	return ch
 }
 
@@ -287,54 +294,3 @@
 	}
 	return nil
 }
-
-// Synchronously fetch this entity's roster from the server and cache
-// that information.
-func (cl *Client) fetchRoster() os.Error {
-	iq := &Iq{From: cl.Jid.String(), Id: <- cl.Id, Type: "get",
-		Query: &RosterQuery{XMLName: xml.Name{Local: "query",
-			Space: NsRoster}}}
-	ch := make(chan os.Error)
-	f := func(st Stanza) bool {
-		iq, ok := st.(*Iq)
-		if !ok {
-			ch <- os.NewError(fmt.Sprintf(
-				"Roster query result not iq: %v", st))
-			return false
-		}
-		if iq.Type == "error" {
-			ch <- iq.Error
-			return false
-		}
-		q := iq.Query
-		if q == nil {
-			ch <- os.NewError(fmt.Sprintf(
-				"Roster query result nil query: %v",
-				iq))
-			return false
-		}
-		cl.roster = make(map[string] *RosterItem, len(q.Item))
-		for _, item := range(q.Item) {
-			cl.roster[item.Jid] = &item
-		}
-		ch <- nil
-		return false
-	}
-	cl.HandleStanza(iq.Id, f)
-	cl.Out <- iq
-	// Wait for f to complete.
-	return <- ch
-}
-
-// BUG(cjyar) The roster isn't actually updated when things change.
-
-// Returns the current roster of other entities which this one has a
-// relationship with. Changes to the roster will be signaled by an
-// appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4.
-func (cl *Client) Roster() map[string] *RosterItem {
-	r := make(map[string] *RosterItem)
-	for key, val := range(cl.roster) {
-		r[key] = val
-	}
-	return r
-}