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 }