Changed the type of structure fields which hold JIDs from string to JID.
packagexmpp// This file contains support for roster management, RFC 3921, Section 7.import("encoding/xml""reflect")// Roster query/resulttypeRosterQuerystruct{XMLNamexml.Name`xml:"jabber:iq:roster query"`Item[]RosterItem`xml:"item"`}// See RFC 3921, Section 7.1.typeRosterItemstruct{XMLNamexml.Name`xml:"jabber:iq:roster item"`Jidstring`xml:"jid,attr"`Subscriptionstring`xml:"subscription,attr"`Namestring`xml:"name,attr"`Group[]string}typeRosterstruct{Extensiongetchan[]RosterItemtoServerchanStanza}typerosterClientstruct{rosterChan<-chan[]RosterItemrosterUpdatechan<-RosterItem}func(r*Roster)rosterMgr(upd<-chanStanza){roster:=make(map[string]RosterItem)varsnapshot[]RosterItemvargetchan<-[]RosterItemfor{select{caseget<-snapshot:casestan,ok:=<-upd:if!ok{return}iq,ok:=stan.(*Iq)if!ok{continue}ifiq.Type!="result"&&iq.Type!="set"{continue}varrq*RosterQueryfor_,ele:=rangeiq.Nested{ifq,ok:=ele.(*RosterQuery);ok{rq=qbreak}}ifrq==nil{continue}for_,item:=rangerq.Item{roster[item.Jid]=item}snapshot=[]RosterItem{}for_,ri:=rangeroster{snapshot=append(snapshot,ri)}get=r.get}}}func(r*Roster)makeFilters()(Filter,Filter){rosterUpdate:=make(chanStanza)gor.rosterMgr(rosterUpdate)recv:=func(in<-chanStanza,outchan<-Stanza){deferclose(out)deferclose(rosterUpdate)forstan:=rangein{rosterUpdate<-stanout<-stan}}send:=func(in<-chanStanza,outchan<-Stanza){deferclose(out)for{select{casestan,ok:=<-in:if!ok{return}out<-stancasestan:=<-r.toServer:out<-stan}}}returnrecv,send}funcnewRosterExt()*Roster{r:=Roster{}r.StanzaTypes=make(map[xml.Name]reflect.Type)rName:=xml.Name{Space:NsRoster,Local:"query"}r.StanzaTypes[rName]=reflect.TypeOf(RosterQuery{})r.RecvFilter,r.SendFilter=r.makeFilters()r.get=make(chan[]RosterItem)r.toServer=make(chanStanza)return&r}// Return the most recent snapshot of the roster status. This is// updated automatically as roster updates are received from the// server. This function may block immediately after the XMPP// connection has been established, until the first roster update is// received from the server.func(r*Roster)Get()[]RosterItem{return<-r.get}// Asynchronously fetch this entity's roster from the server.func(r*Roster)update(){iq:=&Iq{Header:Header{Type:"get",Id:NextId(),Nested:[]interface{}{RosterQuery{}}}}r.toServer<-iq}