--- 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
-}