Step 3 of converting to interface Stanza and embedded struct Header.
--- a/examples/interact.go Sun Dec 16 22:37:57 2012 -0700
+++ b/examples/interact.go Sun Dec 16 23:06:54 2012 -0700
@@ -63,7 +63,7 @@
fmt.Printf("%d: %v\n", i, entry)
}
- go func(ch <-chan interface{}) {
+ go func(ch <-chan xmpp.Stanza) {
for obj := range ch {
fmt.Printf("s: %v\n", obj)
}
@@ -89,7 +89,7 @@
fmt.Println("Couldn't find start element")
break
}
- var stan interface{}
+ var stan xmpp.Stanza
switch se.Name.Local {
case "iq":
stan = &xmpp.Iq{}
--- a/roster.go Sun Dec 16 22:37:57 2012 -0700
+++ b/roster.go Sun Dec 16 23:06:54 2012 -0700
@@ -51,7 +51,7 @@
iq := &Iq{Header: Header{From: client.Jid.String(), Type: "get",
Id: <-Id, Nested: []interface{}{RosterQuery{}}}}
ch := make(chan error)
- f := func(v interface{}) bool {
+ f := func(v Stanza) bool {
defer close(ch)
iq, ok := v.(*Iq)
if !ok {
@@ -91,9 +91,9 @@
// the roster feeder, which is the goroutine that provides data on
// client.Roster.
func startRosterFilter(client *Client) {
- out := make(chan interface{})
+ out := make(chan Stanza)
in := client.AddFilter(out)
- go func(in <-chan interface{}, out chan<- interface{}) {
+ go func(in <-chan Stanza, out chan<- Stanza) {
defer close(out)
for st := range in {
maybeUpdateRoster(client, st)
--- a/stream.go Sun Dec 16 22:37:57 2012 -0700
+++ b/stream.go Sun Dec 16 23:06:54 2012 -0700
@@ -29,7 +29,7 @@
type stanzaHandler struct {
id string
// Return true means pass this to the application
- f func(interface{}) bool
+ f func(Stanza) bool
}
// BUG(cjyar) Review all these *Client receiver methods. They should
@@ -225,10 +225,10 @@
}
}
-func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- interface{}) {
+func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- Stanza) {
defer close(cliOut)
- handlers := make(map[string]func(interface{}) bool)
+ handlers := make(map[string]func(Stanza) bool)
Loop:
for {
select {
@@ -238,7 +238,6 @@
if !ok {
break Loop
}
- var st *Header
switch obj := x.(type) {
case *stream:
handleStream(obj)
@@ -251,24 +250,19 @@
case *auth:
cl.handleSasl(obj)
case Stanza:
- st = obj.GetHeader()
+ send := true
+ id := obj.GetHeader().Id
+ if handlers[id] != nil {
+ f := handlers[id]
+ delete(handlers, id)
+ send = f(obj)
+ }
+ if send {
+ cliOut <- obj
+ }
default:
Warn.Logf("Unhandled non-stanza: %T %#v", x, x)
}
-
- if st == nil {
- continue
- }
-
- send := true
- if handlers[st.Id] != nil {
- f := handlers[st.Id]
- delete(handlers, st.Id)
- send = f(x)
- }
- if send {
- cliOut <- x
- }
}
}
}
@@ -277,11 +271,11 @@
// the app might inject something inappropriate into our negotiations
// with the server. The control channel controls this loop's
// activity.
-func writeStream(srvOut chan<- interface{}, cliIn <-chan interface{},
+func writeStream(srvOut chan<- interface{}, cliIn <-chan Stanza,
control <-chan int) {
defer close(srvOut)
- var input <-chan interface{}
+ var input <-chan Stanza
Loop:
for {
select {
@@ -309,8 +303,8 @@
// Stanzas from the remote go up through a stack of filters to the
// app. This function manages the filters.
-func filterTop(filterOut <-chan <-chan interface{}, filterIn chan<- <-chan interface{},
-topFilter <-chan interface{}, app chan<- interface{}) {
+func filterTop(filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza,
+topFilter <-chan Stanza, app chan<- Stanza) {
defer close(app)
Loop:
for {
@@ -333,7 +327,7 @@
}
}
-func filterBottom(from <-chan interface{}, to chan<- interface{}) {
+func filterBottom(from <-chan Stanza, to chan<- Stanza) {
defer close(to)
for data := range from {
to <- data
@@ -598,7 +592,7 @@
}
msg := &Iq{Header: Header{Type: "set", Id: <-Id,
Nested: []interface{}{bindReq}}}
- f := func(st interface{}) bool {
+ f := func(st Stanza) bool {
iq, ok := st.(*Iq)
if !ok {
Warn.Log("non-iq response")
@@ -643,7 +637,7 @@
// available on the normal Client.In channel. The stanza handler
// must not read from that channel, as deliveries on it cannot proceed
// until the handler returns true or false.
-func (cl *Client) HandleStanza(id string, f func(interface{}) bool) {
+func (cl *Client) HandleStanza(id string, f func(Stanza) bool) {
h := &stanzaHandler{id: id, f: f}
cl.handlers <- h
}
--- a/xmpp.go Sun Dec 16 22:37:57 2012 -0700
+++ b/xmpp.go Sun Dec 16 23:06:54 2012 -0700
@@ -82,18 +82,18 @@
// Incoming XMPP stanzas from the server will be published on
// this channel. Information which is only used by this
// library to set up the XMPP stream will not appear here.
- In <-chan interface{}
+ In <-chan Stanza
// Outgoing XMPP stanzas to the server should be sent to this
// channel.
- Out chan<- interface{}
+ Out chan<- Stanza
xmlOut chan<- interface{}
// Features advertised by the remote. This will be updated
// asynchronously as new features are received throughout the
// connection process. It should not be updated once
// StartSession() returns.
Features *Features
- filterOut chan<- <-chan interface{}
- filterIn <-chan <-chan interface{}
+ filterOut chan<- <-chan Stanza
+ filterIn <-chan <-chan Stanza
}
// Connect to the appropriate server and authenticate as the given JID
@@ -200,23 +200,23 @@
return ch
}
-func (cl *Client) startStreamReader(xmlIn <-chan interface{}, srvOut chan<- interface{}) <-chan interface{} {
- ch := make(chan interface{})
+func (cl *Client) startStreamReader(xmlIn <-chan interface{}, srvOut chan<- interface{}) <-chan Stanza {
+ ch := make(chan Stanza)
go cl.readStream(xmlIn, ch)
return ch
}
-func (cl *Client) startStreamWriter(xmlOut chan<- interface{}) chan<- interface{} {
- ch := make(chan interface{})
+func (cl *Client) startStreamWriter(xmlOut chan<- interface{}) chan<- Stanza {
+ ch := make(chan Stanza)
go writeStream(xmlOut, ch, cl.inputControl)
return ch
}
-func (cl *Client) startFilter(srvIn <-chan interface{}) <-chan interface{} {
- cliIn := make(chan interface{})
- filterOut := make(chan (<-chan interface{}))
- filterIn := make(chan (<-chan interface{}))
- nullFilter := make(chan interface{})
+func (cl *Client) startFilter(srvIn <-chan Stanza) <-chan Stanza {
+ cliIn := make(chan Stanza)
+ filterOut := make(chan (<-chan Stanza))
+ filterIn := make(chan (<-chan Stanza))
+ nullFilter := make(chan Stanza)
go filterBottom(srvIn, nullFilter)
go filterTop(filterOut, filterIn, nullFilter, cliIn)
cl.filterOut = filterOut
@@ -272,7 +272,7 @@
Nested: []interface{}{Generic{XMLName:
xml.Name{Space: NsSession, Local: "session"}}}}}
ch := make(chan error)
- f := func(st interface{}) bool {
+ f := func(st Stanza) bool {
iq, ok := st.(*Iq)
if !ok {
Warn.Log("iq reply not iq; can't start session")
@@ -311,7 +311,7 @@
// 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 interface{}) <-chan interface{} {
+func (cl *Client) AddFilter(out <-chan Stanza) <-chan Stanza {
cl.filterOut <- out
return <-cl.filterIn
}