xmpp.go
changeset 45 abf958bcc201
parent 44 dd6f5cc27d52
child 46 4a4530b8f622
--- a/xmpp.go	Sun Jan 01 17:28:00 2012 -0700
+++ b/xmpp.go	Sun Jan 01 19:00:21 2012 -0700
@@ -73,6 +73,8 @@
 	// StartSession() returns.
 	Features *Features
 	roster map[string] *RosterItem
+	filterOut chan<- <-chan Stanza
+	filterIn <-chan <-chan Stanza
 }
 var _ io.Closer = &Client{}
 
@@ -138,9 +140,13 @@
 
 	// Start the XMPP stream handler which filters stream-level
 	// events and responds to them.
-	clIn := cl.startStreamReader(xmlIn, cl.xmlOut)
+	stIn := cl.startStreamReader(xmlIn, cl.xmlOut)
 	clOut := cl.startStreamWriter(cl.xmlOut)
 
+	// Start the manager for the filters that can modify what the
+	// app sees.
+	clIn := cl.startFilter(stIn)
+
 	// Initial handshake.
 	hsOut := &stream{To: jid.Domain, Version: Version}
 	cl.xmlOut <- hsOut
@@ -189,6 +195,14 @@
 	return ch
 }
 
+func (cl *Client) startFilter(srvIn <-chan Stanza) <-chan Stanza {
+	cliOut := make(chan Stanza)
+	filterOut := make(chan (<-chan Stanza))
+	filterIn := make(chan (<-chan Stanza))
+	go filter(srvIn, cliOut, filterOut, filterIn)
+	return cliOut
+}
+
 func tee(r io.Reader, w io.Writer, prefix string) {
 	defer tryClose(r, w)
 
@@ -294,3 +308,13 @@
 	}
 	return nil
 }
+
+// AddFilter adds a new filter to the top of the stack through which
+// incoming stanzas travel on their way up to the client. The new
+// filter's output channel is given to this function, and it returns a
+// new input channel which the filter should read from. When its input
+// channel closes, the filter should close its output channel.
+func (cl *Client) AddFilter(out <-chan Stanza) <-chan Stanza {
+	cl.filterOut <- out
+	return <- cl.filterIn
+}