--- 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
+}