1
2
3
4
5 package objabi
6
7 import (
8 "fmt"
9 "strconv"
10 "strings"
11 )
12
13
14
15
16
17
18 func PathToPrefix(s string) string {
19 slash := strings.LastIndex(s, "/")
20
21 n := 0
22 for r := 0; r < len(s); r++ {
23 if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
24 n++
25 }
26 }
27
28
29 if n == 0 {
30 return s
31 }
32
33
34 const hex = "0123456789abcdef"
35 p := make([]byte, 0, len(s)+2*n)
36 for r := 0; r < len(s); r++ {
37 if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
38 p = append(p, '%', hex[c>>4], hex[c&0xF])
39 } else {
40 p = append(p, c)
41 }
42 }
43
44 return string(p)
45 }
46
47
48
49 func PrefixToPath(s string) (string, error) {
50 percent := strings.IndexByte(s, '%')
51 if percent == -1 {
52 return s, nil
53 }
54
55 p := make([]byte, 0, len(s))
56 for i := 0; i < len(s); {
57 if s[i] != '%' {
58 p = append(p, s[i])
59 i++
60 continue
61 }
62 if i+2 >= len(s) {
63
64
65 return "", fmt.Errorf("malformed prefix %q: escape sequence must contain two hex digits", s)
66 }
67
68 b, err := strconv.ParseUint(s[i+1:i+3], 16, 8)
69 if err != nil {
70
71 return "", fmt.Errorf("malformed prefix %q: escape sequence %q must contain two hex digits", s, s[i:i+3])
72 }
73
74 p = append(p, byte(b))
75 i += 3
76 }
77 return string(p), nil
78 }
79
View as plain text