-
Notifications
You must be signed in to change notification settings - Fork 7
/
nodekind.go
152 lines (138 loc) · 3.34 KB
/
nodekind.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package xmlwriter
import (
"fmt"
"strings"
)
// NodeKind is the kind of the node. Yep.
type NodeKind int
// Name returns a stable name for the NodeKind. If the NodeKind is invalid,
// the Name() will be empty. String() returns a human-readable representation
// for information purposes; if a stable string is required, use this instead.
func (n NodeKind) Name() string {
if int(n) < nodeKindLength {
return kindName[n]
}
return ""
}
// String returns a human-readable representation of the NodeKind. If a stable
// string is required, use Name().
func (n NodeKind) String() string {
s := n.Name()
if s == "" {
s = "<unknown>"
}
return fmt.Sprintf("%s(%d)", s, n)
}
func (n NodeKind) flag() nodeFlag {
return kindFlag[n]
}
// Range of allowed NodeKind values.
const (
NoNode NodeKind = iota
AttrNode
CDataNode
CDataContentNode
CommentNode
CommentContentNode
DTDNode
DTDAttListNode
DTDAttrNode
DTDElemNode
DTDEntityNode
DocNode
ElemNode
NotationNode
PINode
RawNode
TextNode
nodeKindLength int = iota
)
var kindName = [nodeKindLength]string{
NoNode: "none",
AttrNode: "attr",
CDataNode: "cdata",
CDataContentNode: "cdatacontent",
CommentNode: "comment",
CommentContentNode: "commentcontent",
DTDNode: "dtd",
DTDAttListNode: "dtdattlist",
DTDAttrNode: "dtdattr",
DTDElemNode: "dtdelem",
DTDEntityNode: "dtdentity",
DocNode: "document",
ElemNode: "elem",
NotationNode: "notation",
RawNode: "raw",
TextNode: "text",
}
type nodeFlag int
const (
noNodeFlag nodeFlag = 1 << iota
attrNodeFlag
cDataNodeFlag
cDataContentNodeFlag
commentNodeFlag
commentContentNodeFlag
dtdNodeFlag
dtdAttListNodeFlag
dtdAttrNodeFlag
dtdElemNodeFlag
dtdEntityNodeFlag
docNodeFlag
elemNodeFlag
notationNodeFlag
pINodeFlag
rawNodeFlag
textNodeFlag
)
var kindFlag = [nodeKindLength]nodeFlag{
NoNode: noNodeFlag,
AttrNode: attrNodeFlag,
CDataNode: cDataNodeFlag,
CDataContentNode: cDataContentNodeFlag,
CommentNode: commentNodeFlag,
CommentContentNode: commentContentNodeFlag,
DTDNode: dtdNodeFlag,
DTDAttListNode: dtdAttListNodeFlag,
DTDAttrNode: dtdAttrNodeFlag,
DTDElemNode: dtdElemNodeFlag,
DTDEntityNode: dtdEntityNodeFlag,
DocNode: docNodeFlag,
ElemNode: elemNodeFlag,
NotationNode: notationNodeFlag,
RawNode: rawNodeFlag,
TextNode: textNodeFlag,
}
func (set nodeFlag) names() string {
switch set {
case noNodeFlag:
return "none"
case noNodeFlag | cDataNodeFlag:
return "none, cdata"
case noNodeFlag | commentNodeFlag:
return "none, comment"
case noNodeFlag | docNodeFlag:
return "none, document"
case noNodeFlag | dtdNodeFlag:
return "none, dtd"
case noNodeFlag | dtdAttListNodeFlag:
return "none, dtdattlist"
case noNodeFlag | elemNodeFlag:
return "none, elem"
case noNodeFlag | docNodeFlag | dtdNodeFlag | elemNodeFlag:
return "none, document, dtd, elem"
case noNodeFlag | docNodeFlag | elemNodeFlag:
return "none, document, elem"
default:
var names = make([]string, 0, 4)
for i := 0; i < nodeKindLength; i++ {
nk := NodeKind(i)
if set&nk.flag() != 0 {
names = append(names, nk.Name())
}
}
out := strings.Join(names, ", ")
// panic(out)
return out
}
}