-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
token.go
70 lines (61 loc) · 2.42 KB
/
token.go
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
62
63
64
65
66
67
68
69
70
package xmltokenizer
import "sync"
var pool = sync.Pool{New: func() any { return new(Token) }}
// GetToken gets token from the pool, don't forget to put it back.
func GetToken() *Token { return pool.Get().(*Token) }
// PutToken puts token back to the pool.
func PutToken(t *Token) { pool.Put(t) }
// Token represent a single token, one of these following:
// - <?xml version="1.0" encoding="UTF-8"?>
// - <name attr="value" attr="value">
// - <name attr="value" attr="value">CharData
// - <name attr="value" attr="value"><![CDATA[ CharData ]]>
// - <name attr="value" attr="value"/>
// - </name>
// - <!-- a comment -->
// - <!DOCTYPE library [
// <!ELEMENT library (book+)>
// <!ELEMENT book (title, author, year)>
// ]>
//
// Token includes CharData or CDATA in Data field when it appears right after the start element.
type Token struct {
Name Name // Name is an XML name, empty when a tag starts with "<?" or "<!".
Attrs []Attr // Attrs exist when len(Attrs) > 0.
Data []byte // Data could be a CharData or a CDATA, or maybe a RawToken if a tag starts with "<?" or "<!" (except "<![CDATA").
SelfClosing bool // True when a tag ends with "/>" e.g. <c r="E3" s="1" />. Also true when a tag starts with "<?" or "<!" (except "<![CDATA").
IsEndElement bool // True when a tag start with "</" e.g. </gpx> or </gpxtpx:atemp>.
}
// IsEndElementOf checks whether the given token represent a
// n end element (closing tag) of given StartElement.
func (t *Token) IsEndElementOf(se *Token) bool {
if t.IsEndElement &&
string(t.Name.Full) == string(se.Name.Full) {
return true
}
return false
}
// Copy copies src Token into t, returning t. Attrs should be
// consumed immediately since it's only being shallow copied.
func (t *Token) Copy(src Token) *Token {
t.Name.Prefix = append(t.Name.Prefix[:0], src.Name.Prefix...)
t.Name.Local = append(t.Name.Local[:0], src.Name.Local...)
t.Name.Full = append(t.Name.Full[:0], src.Name.Full...)
t.Attrs = append(t.Attrs[:0], src.Attrs...) // shallow copy
t.Data = append(t.Data[:0], src.Data...)
t.SelfClosing = src.SelfClosing
t.IsEndElement = src.IsEndElement
return t
}
// Attr represents an XML attribute.
type Attr struct {
Name Name
Value []byte
}
// Name represents an XML name <prefix:local>,
// we don't manage the bookkeeping of namespaces.
type Name struct {
Prefix []byte
Local []byte
Full []byte // Full is combination of "prefix:local"
}