stream.go
changeset 13 c9527bbe99a6
parent 12 122ab6208c3c
child 14 fd6781a41e6f
equal deleted inserted replaced
12:122ab6208c3c 13:c9527bbe99a6
    23 	"regexp"
    23 	"regexp"
    24 	"strings"
    24 	"strings"
    25 	"time"
    25 	"time"
    26 	"xml"
    26 	"xml"
    27 )
    27 )
       
    28 
       
    29 type stanzaHandler struct {
       
    30 	id string
       
    31 	f func(Stanza) bool
       
    32 }
    28 
    33 
    29 func (cl *Client) readTransport(w io.Writer) {
    34 func (cl *Client) readTransport(w io.Writer) {
    30 	defer tryClose(cl.socket, w)
    35 	defer tryClose(cl.socket, w)
    31 	cl.socket.SetReadTimeout(1e8)
    36 	cl.socket.SetReadTimeout(1e8)
    32 	p := make([]byte, 1024)
    37 	p := make([]byte, 1024)
   169 }
   174 }
   170 
   175 
   171 func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- interface{}) {
   176 func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- interface{}) {
   172 	defer tryClose(srvIn, cliOut)
   177 	defer tryClose(srvIn, cliOut)
   173 
   178 
   174 	for x := range srvIn {
   179 	handlers := make(map[string] func(Stanza) bool)
   175 		switch obj := x.(type) {
   180 	// TODO This for loop will never terminate, even when the
   176 		case *Stream:
   181 	// channels are closed.
   177 			handleStream(obj)
   182 	for {
   178 		case *Features:
   183 		select {
   179 			cl.handleFeatures(obj)
   184 		case h := <- cl.handlers:
   180 		case *starttls:
   185 			handlers[h.id] = h.f
   181 			cl.handleTls(obj)
   186 		case x := <- srvIn:
   182 		case *auth:
   187 			send := false
   183 			cl.handleSasl(obj)
   188 			switch obj := x.(type) {
   184 		default:
   189 			case *Stream:
   185 			cliOut <- x
   190 				handleStream(obj)
       
   191 			case *Features:
       
   192 				cl.handleFeatures(obj)
       
   193 			case *starttls:
       
   194 				cl.handleTls(obj)
       
   195 			case *auth:
       
   196 				cl.handleSasl(obj)
       
   197 			default:
       
   198 				send = true
       
   199 			}
       
   200 			if st, ok := x.(Stanza) ; ok &&
       
   201 				handlers[st.XId()] != nil {
       
   202 				f := handlers[st.XId()]
       
   203 				send = f(st)
       
   204 			}
       
   205 			if send {
       
   206 				cliOut <- x
       
   207 			}
   186 		}
   208 		}
   187 	}
   209 	}
   188 }
   210 }
   189 
   211 
   190 func writeStream(srvOut chan<- interface{}, cliIn <-chan interface{}) {
   212 func writeStream(srvOut chan<- interface{}, cliIn <-chan interface{}) {
   453 				"resource"}, Chardata: res}
   475 				"resource"}, Chardata: res}
   454 	}
   476 	}
   455 	cl.xmlOut <- msg
   477 	cl.xmlOut <- msg
   456 	// TODO Grab the iq result from the server and update cl.Jid.
   478 	// TODO Grab the iq result from the server and update cl.Jid.
   457 }
   479 }
       
   480 
       
   481 func (cl *Client) HandleStanza(id string, f func(Stanza) bool) {
       
   482 	h := &stanzaHandler{id: id, f: f}
       
   483 	cl.handlers <- h
       
   484 }