summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-06-30 11:56:59 +0200
committerxengineering <me@xengineering.eu>2023-06-30 11:56:59 +0200
commitc224e6ebc23d96929d9c3fee9b7987762f68f1dd (patch)
tree7f3946d8384cf5622c4fb8b24e6b9d90fce6dc5b
parentc8544b19df055235b9106ff296f0a5fe7cb1fe91 (diff)
downloadlimox-c224e6ebc23d96929d9c3fee9b7987762f68f1dd.tar
limox-c224e6ebc23d96929d9c3fee9b7987762f68f1dd.tar.zst
limox-c224e6ebc23d96929d9c3fee9b7987762f68f1dd.zip
Add xmpp/router.go
This implements a routing function for XML elements received by an XML stream.
-rw-r--r--xmpp/router.go59
-rw-r--r--xmpp/stream_pair.go8
2 files changed, 60 insertions, 7 deletions
diff --git a/xmpp/router.go b/xmpp/router.go
new file mode 100644
index 0000000..839f870
--- /dev/null
+++ b/xmpp/router.go
@@ -0,0 +1,59 @@
+package xmpp
+
+import (
+ "encoding/xml"
+ "log"
+)
+
+// routingTable is a data structure which contains routing information for XML
+// elements. The xml.StartElement at the beginning of an XML element has a name
+// containing the XML namespace and a local name. Based on this compisition
+// which forms the xml.Name the appropriate handler function is defined by each
+// entry of the routingTable.
+type routingTable []struct {
+ name xml.Name
+ handler func([]xml.Token)
+}
+
+// getRoutingTable returns the routing table used in
+// xengineering.eu/limox/xmpp. Since Go does not allow such a datatype as a
+// constant such a function is a simple yet inefficient approach to guarantee
+// that an unmodified routing table is delivered to each user. A global
+// variable would have the problem that it could be altered during execution.
+func getRoutingTable() routingTable {
+ return routingTable{
+ // TODO fill with entries
+ }
+}
+
+// route determines the correct handler function for the given XML element by a
+// given routingTable. In addition it executes the determined handler function.
+// If no handler function is found an error message is send via the log module.
+func route(e []xml.Token, t routingTable) {
+ var name xml.Name
+
+ // TODO a stronger definition of an XML element (as here
+ // https://www.w3schools.com/xml/xml_elements.asp) would define that the
+ // first Token of an element is a StartElement token. This would make this
+ // code easier.
+ escape := false
+ for _, token := range e {
+ switch s := token.(type) {
+ case xml.StartElement:
+ name = s.Name
+ escape = true
+ }
+ if escape {
+ break
+ }
+ }
+
+ for _, r := range t {
+ if name == r.name {
+ r.handler(e)
+ return
+ }
+ }
+
+ log.Println("Could not route XML element")
+}
diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go
index b13d8a3..c9108d1 100644
--- a/xmpp/stream_pair.go
+++ b/xmpp/stream_pair.go
@@ -28,13 +28,7 @@ func runStreamPair(s *session) {
}
if buf.isComplete() {
element := buf.reset()
- // TODO handle XML element here - this is just a dummy:
- switch start := element[0].(type) {
- case xml.StartElement:
- log.Printf("Got XML element `%s`\n", start.Name.Local)
- default:
- log.Println("No xml.StartElement at start of element buffer!")
- }
+ route(element, getRoutingTable())
}
}
}