Minor fixups to make this come closer to working. It doesn't actually
work, though, because the nesting in XML is backwards from how it is
in Go. <iq><query/></iq> vs. RosterIq { Iq }
// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.packagexmppimport("fmt""io""os""xml")// This file contains support for roster management, RFC 3921, Section 7.typeRosterIqstruct{IqQueryRosterQuery}var_ExtendedStanza=&RosterIq{}// Roster query/resulttypeRosterQuerystruct{// Should always be NsRoster, "query"XMLNamexml.NameItem[]RosterItem}// See RFC 3921, Section 7.1.typeRosterItemstruct{// Should always be "item"XMLNamexml.NameJidstring`xml:"attr"`Subscriptionstring`xml:"attr"`Namestring`xml:"attr"`Group[]string}func(riq*RosterIq)MarshalXML()([]byte,os.Error){returnmarshalXML(riq)}func(riq*RosterIq)InnerMarshal(wio.Writer)os.Error{returnxml.Marshal(w,riq.Query)}// Implicitly becomes part of NewClient's extStanza arg.funcrosterStanza(name*xml.Name)ExtendedStanza{return&RosterIq{}}// Synchronously fetch this entity's roster from the server and cache// that information.func(cl*Client)fetchRoster()os.Error{iq:=&RosterIq{Iq:Iq{From:cl.Jid.String(),Id:<-cl.Id,Type:"get"},Query:RosterQuery{XMLName:xml.Name{Local:"query",Space:NsRoster}}}ch:=make(chanos.Error)f:=func(stStanza)bool{iq,ok:=st.(*RosterIq)if!ok{ch<-os.NewError(fmt.Sprintf("Roster query result not iq: %v",st))returnfalse}ifiq.Type=="error"{ch<-iq.Errorreturnfalse}q:=iq.Querycl.roster=make(map[string]*RosterItem,len(q.Item))for_,item:=range(q.Item){cl.roster[item.Jid]=&item}ch<-nilreturnfalse}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)forkey,val:=range(cl.roster){r[key]=val}returnr}