/
escape.go
63 lines (60 loc) · 1.16 KB
/
escape.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
package chstorage
import (
"strings"
"unicode"
"unicode/utf8"
)
func singleQuoted[S ~[]byte | ~string](s S) string {
const lowerhex = "0123456789abcdef"
var sb strings.Builder
sb.Grow(len(s) + 2)
sb.WriteByte('\'')
for _, r := range string(s) {
switch r {
case '\'':
sb.WriteString(`\'`)
case '\\':
sb.WriteString(`\\`)
case '\a':
sb.WriteString(`\a`)
case '\b':
sb.WriteString(`\b`)
case '\f':
sb.WriteString(`\f`)
case '\n':
sb.WriteString(`\n`)
case '\r':
sb.WriteString(`\r`)
case '\t':
sb.WriteString(`\t`)
case '\v':
sb.WriteString(`\v`)
default:
if unicode.IsPrint(r) {
sb.WriteRune(r)
continue
}
switch {
case r < ' ' || r == 0x7f:
sb.WriteString(`\x`)
sb.WriteByte(lowerhex[byte(r)>>4])
sb.WriteByte(lowerhex[byte(r)&0xF])
case !utf8.ValidRune(r):
r = 0xFFFD
fallthrough
case r < 0x10000:
sb.WriteString(`\u`)
for s := 12; s >= 0; s -= 4 {
sb.WriteByte(lowerhex[r>>uint(s)&0xF])
}
default:
sb.WriteString(`\U`)
for s := 28; s >= 0; s -= 4 {
sb.WriteByte(lowerhex[r>>uint(s)&0xF])
}
}
}
}
sb.WriteByte('\'')
return sb.String()
}