go-tg-screenshot-bot
84 строки · 2.0 Кб
1package dbus
2
3import "net/url"
4
5// EscapeBusAddressValue implements a requirement to escape the values
6// in D-Bus server addresses, as defined by the D-Bus specification at
7// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
8func EscapeBusAddressValue(val string) string {
9toEsc := strNeedsEscape(val)
10if toEsc == 0 {
11// Avoid unneeded allocation/copying.
12return val
13}
14
15// Avoid allocation for short paths.
16var buf [64]byte
17var out []byte
18// Every to-be-escaped byte needs 2 extra bytes.
19required := len(val) + 2*toEsc
20if required <= len(buf) {
21out = buf[:required]
22} else {
23out = make([]byte, required)
24}
25
26j := 0
27for i := 0; i < len(val); i++ {
28if ch := val[i]; needsEscape(ch) {
29// Convert ch to %xx, where xx is hex value.
30out[j] = '%'
31out[j+1] = hexchar(ch >> 4)
32out[j+2] = hexchar(ch & 0x0F)
33j += 3
34} else {
35out[j] = ch
36j++
37}
38}
39
40return string(out)
41}
42
43// UnescapeBusAddressValue unescapes values in D-Bus server addresses,
44// as defined by the D-Bus specification at
45// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
46func UnescapeBusAddressValue(val string) (string, error) {
47// Looks like url.PathUnescape does exactly what is required.
48return url.PathUnescape(val)
49}
50
51// hexchar returns an octal representation of a n, where n < 16.
52// For invalid values of n, the function panics.
53func hexchar(n byte) byte {
54const hex = "0123456789abcdef"
55
56// For n >= len(hex), runtime will panic.
57return hex[n]
58}
59
60// needsEscape tells if a byte is NOT one of optionally-escaped bytes.
61func needsEscape(c byte) bool {
62if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
63return false
64}
65switch c {
66case '-', '_', '/', '\\', '.', '*':
67return false
68}
69
70return true
71}
72
73// strNeedsEscape tells how many bytes in the string need escaping.
74func strNeedsEscape(val string) int {
75count := 0
76
77for i := 0; i < len(val); i++ {
78if needsEscape(val[i]) {
79count++
80}
81}
82
83return count
84}
85