roster.go
changeset 46 4a4530b8f622
parent 42 f6bb47ca12f2
child 47 22e575eff35a
equal deleted inserted replaced
45:abf958bcc201 46:4a4530b8f622
    60 	cl.Out <- iq
    60 	cl.Out <- iq
    61 	// Wait for f to complete.
    61 	// Wait for f to complete.
    62 	return <- ch
    62 	return <- ch
    63 }
    63 }
    64 
    64 
    65 // BUG(cjyar) The roster isn't actually updated when things change.
       
    66 
       
    67 // Returns the current roster of other entities which this one has a
    65 // Returns the current roster of other entities which this one has a
    68 // relationship with. Changes to the roster will be signaled by an
    66 // relationship with. Changes to the roster will be signaled by an
    69 // appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4.
    67 // appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4.
    70 func (cl *Client) Roster() map[string] *RosterItem {
    68 func (cl *Client) Roster() map[string] *RosterItem {
    71 	r := make(map[string] *RosterItem)
    69 	r := make(map[string] *RosterItem)
    72 	for key, val := range(cl.roster) {
    70 	for key, val := range(cl.roster) {
    73 		r[key] = val
    71 		r[key] = val
    74 	}
    72 	}
    75 	return r
    73 	return r
    76 }
    74 }
       
    75 
       
    76 // The roster filter updates the Client's representation of the
       
    77 // roster, but it lets the relevant stanzas through.
       
    78 func (cl *Client) startRosterFilter() {
       
    79 	out := make(chan Stanza)
       
    80 	in := cl.AddFilter(out)
       
    81 	go func(inSave <-chan Stanza, outSave chan<- Stanza) {
       
    82 		defer close(out)
       
    83 		in := inSave
       
    84 		var out chan<- Stanza
       
    85 		var st Stanza
       
    86 		var ok bool
       
    87 		for {
       
    88 			select {
       
    89 			case st, ok = <- in:
       
    90 				if !ok {
       
    91 					break
       
    92 				}
       
    93 				cl.maybeUpdateRoster(st)
       
    94 				in = nil
       
    95 				out = outSave
       
    96 			case out <- st:
       
    97 				out = nil
       
    98 				in = inSave
       
    99 			}
       
   100 		}
       
   101 	}(in, out)
       
   102 }
       
   103 
       
   104 func (cl *Client) maybeUpdateRoster(st Stanza) {
       
   105 	rq, ok := st.GetNested().(*RosterQuery)
       
   106 	if st.GetName() == "iq" && st.GetType() == "set" && ok {
       
   107 		for _, item := range(rq.Item) {
       
   108 			cl.roster[item.Jid] = &item
       
   109 		}
       
   110 	}
       
   111 }