-
Notifications
You must be signed in to change notification settings - Fork 0
/
escape.go
93 lines (81 loc) · 1.46 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
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
package treerack
func runesContain(rs []rune, r rune) bool {
for _, ri := range rs {
if ri == r {
return true
}
}
return false
}
func escapeChar(escape, c rune) []rune {
switch c {
case '\b':
return []rune{escape, 'b'}
case '\f':
return []rune{escape, 'f'}
case '\n':
return []rune{escape, 'n'}
case '\r':
return []rune{escape, 'r'}
case '\t':
return []rune{escape, 't'}
case '\v':
return []rune{escape, 'v'}
default:
return []rune{escape, c}
}
}
func escape(escape rune, banned, chars []rune) []rune {
var escaped []rune
for i := range chars {
if runesContain(banned, chars[i]) {
escaped = append(escaped, escapeChar(escape, chars[i])...)
continue
}
escaped = append(escaped, chars[i])
}
return escaped
}
func unescapeChar(c rune) rune {
switch c {
case 'b':
return '\b'
case 'f':
return '\f'
case 'n':
return '\n'
case 'r':
return '\r'
case 't':
return '\t'
case 'v':
return '\v'
default:
return c
}
}
func unescape(escape rune, banned, chars []rune) ([]rune, error) {
var (
unescaped []rune
escaped bool
)
for _, ci := range chars {
if escaped {
unescaped = append(unescaped, unescapeChar(ci))
escaped = false
continue
}
switch {
case ci == escape:
escaped = true
case runesContain(banned, ci):
return nil, ErrInvalidEscapeCharacter
default:
unescaped = append(unescaped, ci)
}
}
if escaped {
return nil, ErrInvalidEscapeCharacter
}
return unescaped, nil
}