-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtag_scanner.go
129 lines (104 loc) · 1.66 KB
/
tag_scanner.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
package validator
type (
tagScanner struct {
buf string
pos int
}
tagParamsScanner struct {
buf string
pos int
}
tagToken int
)
const (
illegal tagToken = iota
eof
tagSeparator
orSeparator
nextSeparator
)
func newTagScanner(buf string) *tagScanner {
return &tagScanner{buf: buf}
}
func (s *tagScanner) Scan() (tagToken, string) {
var (
lit []byte
depthParen int
)
for {
if s.eof() {
break
}
ch := s.read()
switch ch {
case ' ', '\t', '\r', '\n':
if depthParen == 0 {
continue
}
case ',':
if depthParen == 0 {
return tagSeparator, string(lit)
}
case '|':
if depthParen == 0 {
return orSeparator, string(lit)
}
case ';':
if depthParen == 0 {
return nextSeparator, string(lit)
}
case '(':
depthParen++
case ')':
depthParen--
}
lit = append(lit, ch)
}
return eof, string(lit)
}
func (s *tagScanner) read() (ch byte) {
ch = s.buf[s.pos]
s.pos++
return
}
func (s *tagScanner) eof() bool {
return len(s.buf) == s.pos
}
func newTagParamsScanner(buf string) *tagParamsScanner {
return &tagParamsScanner{buf: buf}
}
func (s *tagParamsScanner) Scan() (tagToken, string) {
var lit []byte
for {
if s.eof() {
break
}
ch := s.read()
switch ch {
case '|':
return orSeparator, string(lit)
case '\\':
switch s.read() {
case '|':
ch = '|'
default:
s.unread()
}
}
lit = append(lit, ch)
}
return eof, string(lit)
}
func (s *tagParamsScanner) read() (ch byte) {
ch = s.buf[s.pos]
s.pos++
return
}
func (s *tagParamsScanner) unread() {
if s.pos > 0 {
s.pos--
}
}
func (s *tagParamsScanner) eof() bool {
return len(s.buf) == s.pos
}