...
1 package pat
2
3 import "net/url"
4
5
6
7 func ishex(c byte) bool {
8 switch {
9 case '0' <= c && c <= '9':
10 return true
11 case 'a' <= c && c <= 'f':
12 return true
13 case 'A' <= c && c <= 'F':
14 return true
15 }
16 return false
17 }
18
19 func unhex(c byte) byte {
20 switch {
21 case '0' <= c && c <= '9':
22 return c - '0'
23 case 'a' <= c && c <= 'f':
24 return c - 'a' + 10
25 case 'A' <= c && c <= 'F':
26 return c - 'A' + 10
27 }
28 return 0
29 }
30
31 func unescape(s string) (string, error) {
32
33 n := 0
34 for i := 0; i < len(s); {
35 switch s[i] {
36 case '%':
37 n++
38 if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
39 s = s[i:]
40 if len(s) > 3 {
41 s = s[:3]
42 }
43 return "", url.EscapeError(s)
44 }
45 i += 3
46 default:
47 i++
48 }
49 }
50
51 if n == 0 {
52 return s, nil
53 }
54
55 t := make([]byte, len(s)-2*n)
56 j := 0
57 for i := 0; i < len(s); {
58 switch s[i] {
59 case '%':
60 t[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
61 j++
62 i += 3
63 default:
64 t[j] = s[i]
65 j++
66 i++
67 }
68 }
69 return string(t), nil
70 }
71
View as plain text