summaryrefslogtreecommitdiff
path: root/xmpp/element_buffer.go
blob: 7792db27185654a610cece1a997f97f2bb32d4cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
}