summaryrefslogtreecommitdiff
path: root/xmpp/element_buffer.go
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/element_buffer.go')
-rw-r--r--xmpp/element_buffer.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/xmpp/element_buffer.go b/xmpp/element_buffer.go
new file mode 100644
index 0000000..7792db2
--- /dev/null
+++ b/xmpp/element_buffer.go
@@ -0,0 +1,61 @@
+package xmpp
+
+import (
+ "encoding/xml"
+)
+
+// elementBuffer is a struct to store multiple values of type xml.Token until
+// they form a complete XML element with opening and closing tag which is
+// suitable to be passed to an appropriate handler function.
+type elementBuffer struct {
+ tokens []xml.Token
+ end xml.EndElement
+ level int
+}
+
+// newElementBuffer returns a new initialized elementBuffer struct.
+func newElementBuffer() elementBuffer {
+ buf := elementBuffer{}
+ buf.reset()
+ return buf
+}
+
+// FIXME this function needs essential error handling for corner cases!
+//
+// add is able to add a new xml.Token to the buffer. There are some rules
+// checked to ensure a correct and consistent elementBuffer which are checked.
+// If one of these checks fail the token is not added and a corresponding error
+// is returned.
+func (e *elementBuffer) add(t xml.Token) error {
+ switch t.(type) {
+ case xml.StartElement:
+ e.level += 1
+ case xml.EndElement:
+ e.level -= 1
+ }
+ e.tokens = append(e.tokens, t)
+ return nil
+}
+
+// FIXME isComplete would be true if a stream with only one XML comment is
+// passed to the buffer. This might be unexpected behaviour.
+//
+// isComplete returns true if the buffer contains a slice of XML tokens which
+// form a complete XML element starting with an xml.StartElement and closing
+// with the corresponding xml.EndElement.
+func (e *elementBuffer) isComplete() bool {
+ return (len(e.tokens) > 0 && e.level == 0)
+}
+
+// reset returns the content of the buffer as a slice of XML tokens and resets
+// the buffer to the initial state. This function can be used to initialize the
+// elementBuffer struct. In that case the return value can be ignored.
+func (e *elementBuffer) reset() (buf []xml.Token) {
+ retval := e.tokens
+
+ e.tokens = make([]xml.Token, 0)
+ e.end = xml.EndElement{}
+ e.level = 0
+
+ return retval
+}