summaryrefslogtreecommitdiff
path: root/xmpp/routing.go
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-05-20 22:33:56 +0200
committerxengineering <me@xengineering.eu>2023-05-21 10:47:58 +0200
commite386931283f3752d581530665a9c6616851aa536 (patch)
tree845d67f68bfff039827e008041858ebcac2805c7 /xmpp/routing.go
parent7b29491f10ee31d0c275fa69d96c3ac6af8fa7a7 (diff)
downloadlimox-e386931283f3752d581530665a9c6616851aa536.tar
limox-e386931283f3752d581530665a9c6616851aa536.tar.zst
limox-e386931283f3752d581530665a9c6616851aa536.zip
Implement xengineering.eu/xmpp.tokenRouter
This will collect XML tokens until a full XML element is received and can be routed by a to-implement elementRouter.
Diffstat (limited to 'xmpp/routing.go')
-rw-r--r--xmpp/routing.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/xmpp/routing.go b/xmpp/routing.go
new file mode 100644
index 0000000..8af3190
--- /dev/null
+++ b/xmpp/routing.go
@@ -0,0 +1,51 @@
+package xmpp
+
+import (
+ "encoding/xml"
+ "errors"
+ "log"
+)
+
+type tokenRouter struct {
+ start xml.StartElement
+ end xml.EndElement
+ buffer []xml.Token
+ level uint16 // XML nesting level
+ enc *encoder
+}
+
+func newTokenRouter(e *encoder) tokenRouter {
+ return tokenRouter{
+ buffer: make([]xml.Token, 0),
+ level: 0,
+ enc: e,
+ }
+}
+
+func (r *tokenRouter) route(t xml.Token) error {
+ r.buffer = append(r.buffer, t)
+
+ switch unwrapped := t.(type) {
+ case xml.StartElement:
+ r.level += 1
+ if r.level == 1 {
+ r.start = unwrapped
+ // call start handler
+ }
+ case xml.EndElement:
+ if r.level == 0 {
+ log.Println("Ignoring XML end element on nesting level zero")
+ return nil
+ }
+ r.level -= 1
+ switch r.level {
+ case 0:
+ return errors.New("Stream was closed by server")
+ case 1:
+ // call elementRouter
+ r.buffer = r.buffer[:1]
+ }
+ }
+
+ return nil
+}