summaryrefslogtreecommitdiff
path: root/xmpp/xml.go
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/xml.go')
-rw-r--r--xmpp/xml.go80
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
+ }
+ }
+ }
+}