roster.go
changeset 126 367e76b3028e
parent 125 f464f14e39a7
child 127 a8f9a0c07fc8
--- a/roster.go	Mon Sep 02 20:46:23 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-// 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.
-
-package xmpp
-
-// This file contains support for roster management, RFC 3921, Section 7.
-
-import (
-	"encoding/xml"
-)
-
-// Roster query/result
-type RosterQuery struct {
-	XMLName xml.Name     `xml:"jabber:iq:roster query"`
-	Item    []RosterItem `xml:"item"`
-}
-
-// See RFC 3921, Section 7.1.
-type RosterItem struct {
-	XMLName      xml.Name `xml:"jabber:iq:roster item"`
-	Jid          string   `xml:"jid,attr"`
-	Subscription string   `xml:"subscription,attr"`
-	Name         string   `xml:"name,attr"`
-	Group        []string
-}
-
-type rosterCb struct {
-	id string
-	cb func()
-}
-
-type Roster struct {
-	Extension
-	get chan []RosterItem
-	callbacks chan rosterCb
-	toServer chan Stanza
-}
-
-type rosterClient struct {
-	rosterChan   <-chan []RosterItem
-	rosterUpdate chan<- RosterItem
-}
-
-// Implicitly becomes part of NewClient's extStanza arg.
-func newRosterQuery(name *xml.Name) interface{} {
-	return &RosterQuery{}
-}
-
-func (r *Roster) rosterMgr(upd <-chan Stanza) {
-	roster := make(map[string]RosterItem)
-	waits := make(map[string]func())
-	var snapshot []RosterItem
-	for {
-		select {
-		case stan, ok := <- upd:
-			if !ok {
-				return
-			}
-			hdr := stan.GetHeader()
-			if f := waits[hdr.Id] ; f != nil {
-				delete(waits, hdr.Id)
-				f()
-			}
-			iq, ok := stan.(*Iq)
-			if iq.Type != "set" {
-				continue
-			}
-			var rq *RosterQuery
-			for _, ele := range iq.Nested {
-				if q, ok := ele.(*RosterQuery); ok {
-					rq = q
-					break
-				}
-			}
-			if rq == nil {
-				continue
-			}
-			for _, item := range rq.Item {
-				roster[item.Jid] = item
-			}
-			snapshot = []RosterItem{}
-			for _, ri := range roster {
-				snapshot = append(snapshot, ri)
-			}
-		case r.get <- snapshot:
-		case cb := <- r.callbacks:
-			waits[cb.id] = cb.cb
-		}
-	}
-}
-
-func (r *Roster) makeFilters() (Filter, Filter) {
-	rosterUpdate := make(chan Stanza)
-	go r.rosterMgr(rosterUpdate)
-	recv := func(in <-chan Stanza, out chan<- Stanza) {
-		defer close(out)
-		for stan := range in {
-			rosterUpdate <- stan
-			out <- stan
-		}
-	}
-	send := func(in <-chan Stanza, out chan<- Stanza) {
-		defer close(out)
-		for {
-			select {
-			case stan, ok := <- in:
-				if !ok {
-					return
-				}
-				out <- stan
-			case stan := <- r.toServer:
-				out <- stan
-			}
-		}
-	}
-	return recv, send
-}
-
-func newRosterExt() *Roster {
-	r := Roster{}
-	r.StanzaHandlers = make(map[string]func(*xml.Name) interface{})
-	r.StanzaHandlers[NsRoster] = newRosterQuery
-	r.RecvFilter, r.SendFilter = r.makeFilters()
-	r.get = make(chan []RosterItem)
-	r.callbacks = make(chan rosterCb)
-	r.toServer = make(chan Stanza)
-	return &r
-}
-
-// Return the most recent snapshot of the roster status. This is
-// updated automatically as roster updates are received from the
-// server, but especially in response to calls to Update().
-func (r *Roster) Get() []RosterItem {
-	return <-r.get
-}
-
-// Synchronously fetch this entity's roster from the server and cache
-// that information. The client can access the roster by watching for
-// RosterQuery objects or by calling Get().
-func (r *Roster) Update() {
-	iq := &Iq{Header: Header{Type: "get", Id: NextId(),
-		Nested: []interface{}{RosterQuery{}}}}
-	waitchan := make(chan int)
-	done := func() {
-		close(waitchan)
-	}
-	r.waitFor(iq.Id, done)
-	r.toServer <- iq
-	<-waitchan
-}
-
-func (r *Roster) waitFor(id string, cb func()) {
-	r.callbacks <- rosterCb{id: id, cb: cb}
-}