1package xmpp 2 3import ( 4 "bytes" 5 "encoding/xml" 6 "fmt" 7 "time" 8 9 "github.com/coyim/coyim/xmpp/data" 10) 11 12const requestDelimiterXML = ` 13<iq type='get' id='%x'> 14 <query xmlns='jabber:iq:private'> 15 <roster xmlns='roster:delimiter'/> 16 </query> 17</iq> 18` 19 20type rosterDelimiter struct { 21 XMLName xml.Name `xml:"roster:delimiter roster"` 22 delimiter string `xml:",chardata"` 23} 24 25type rosterQuery struct { 26 XMLName xml.Name `xml:"jabber:iq:private query"` 27 delimiter rosterDelimiter `xml:"roster:delimiter roster"` 28} 29 30// GetRosterDelimiter blocks and waits for the roster delimiter to be delivered 31func (c *conn) GetRosterDelimiter() (string, error) { 32 rep, _, err := c.RequestRosterDelimiter() 33 if err != nil { 34 return "", err 35 } 36 37 select { 38 case iqStanza := <-rep: 39 stanza, ok := iqStanza.Value.(*data.ClientIQ) 40 if ok { 41 var rst rosterQuery 42 if err := xml.NewDecoder(bytes.NewBuffer(stanza.Query)).Decode(&rst); err != nil || len(rst.delimiter.delimiter) == 0 { 43 return "", nil 44 } 45 return rst.delimiter.delimiter, nil 46 } 47 case <-time.After(5000 * time.Millisecond): 48 } 49 50 return "", nil 51} 52 53// RequestRosterDelimiter will request the roster delimiter 54func (c *conn) RequestRosterDelimiter() (<-chan data.Stanza, data.Cookie, error) { 55 cookie := c.getCookie() 56 if _, err := fmt.Fprintf(c.out, requestDelimiterXML, cookie); err != nil { 57 return nil, 0, err 58 } 59 60 return c.createInflight(cookie, "") 61} 62