diff options
Diffstat (limited to 'xmpp/xml.go')
-rw-r--r-- | xmpp/xml.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/xmpp/xml.go b/xmpp/xml.go new file mode 100644 index 0000000..b0ea77b --- /dev/null +++ b/xmpp/xml.go @@ -0,0 +1,80 @@ +package xmpp + +import ( + "encoding/xml" + "errors" + "io" + "log" +) + +type encoderDecoder struct { + session *session + tx *xml.Encoder + rx *xml.Decoder + terminator chan bool +} + +func newEncoderDecoder(s *session) encoderDecoder { + ed := encoderDecoder{} + + ed.session = s + + lw := logger{"[TX] "} + w := io.MultiWriter(s.transport, lw) + ed.tx = xml.NewEncoder(w) + ed.tx.Indent("", "") + + lr := logger{"[RX] "} + r := io.TeeReader(s.transport, lr) + ed.rx = xml.NewDecoder(r) + + return ed +} + +func (ed *encoderDecoder) encodeToken(t xml.Token) error { + var err error + defer func() { + if err != nil { + log.Println(err) + } + }() + + err = ed.tx.EncodeToken(t) + if err != nil { + return err + } + err = ed.tx.Flush() + if err != nil { + return err + } + + return nil +} + +func (ed *encoderDecoder) run() { + for { + select { + case <-ed.terminator: + return + default: + t, err := ed.rx.Token() + if t != nil && err == nil { + switch t.(type) { + case xml.ProcInst: + case xml.Directive: + case xml.Comment: + default: + c := xml.CopyToken(t) + ed.session.rx <- c + } + } + if err != nil { + if errors.Is(err, io.EOF) { + return + } + log.Println(err) // FIXME terminate session on error + return + } + } + } +} |