-
Notifications
You must be signed in to change notification settings - Fork 37
/
entity.go
59 lines (52 loc) · 1.15 KB
/
entity.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
package main
import (
"golang.org/x/net/html"
"golang.org/x/text/transform"
)
// An entityDecoder is a Transformer that decodes HTML character entities.
type entityDecoder struct{}
func (entityDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
for nSrc < len(src) && nDst < len(dst) {
if c := src[nSrc]; c != '&' {
dst[nDst] = c
nSrc++
nDst++
continue
}
// Try to decode a character entity.
entityLen := 1
for entityLen < 32 {
if nSrc+entityLen == len(src) {
if atEOF {
break
} else {
err = transform.ErrShortSrc
return
}
}
if b := src[nSrc+entityLen]; 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' || '0' <= b && b <= '9' || entityLen == 1 && b == '#' || b == ';' {
entityLen++
if b == ';' {
break
}
} else {
break
}
}
e := string(src[nSrc : nSrc+entityLen])
decoded := html.UnescapeString(e)
n := copy(dst[nDst:], decoded)
if n < len(decoded) {
err = transform.ErrShortDst
return
}
nSrc += entityLen
nDst += len(decoded)
}
if nSrc < len(src) && err == nil {
err = transform.ErrShortDst
}
return
}
func (entityDecoder) Reset() {
}