2017-10-29 16:38:32 +01:00
|
|
|
package treerack
|
|
|
|
|
|
|
|
func runesContain(rs []rune, r rune) bool {
|
|
|
|
for _, ri := range rs {
|
|
|
|
if ri == r {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2017-11-26 01:49:22 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-10-29 16:38:32 +01:00
|
|
|
func unescapeChar(c rune) rune {
|
|
|
|
switch c {
|
|
|
|
case 'b':
|
|
|
|
return '\b'
|
|
|
|
case 'f':
|
|
|
|
return '\f'
|
2017-11-26 01:49:22 +01:00
|
|
|
case 'n':
|
|
|
|
return '\n'
|
2017-10-29 16:38:32 +01:00
|
|
|
case 'r':
|
|
|
|
return '\r'
|
2017-11-26 01:49:22 +01:00
|
|
|
case 't':
|
|
|
|
return '\t'
|
2017-10-29 16:38:32 +01:00
|
|
|
case 'v':
|
|
|
|
return '\v'
|
|
|
|
default:
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-26 01:49:22 +01:00
|
|
|
func unescape(escape rune, banned, chars []rune) ([]rune, error) {
|
2017-10-29 16:38:32 +01:00
|
|
|
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
|
|
|
|
}
|