123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package dbus
- import "net/url"
- // EscapeBusAddressValue implements a requirement to escape the values
- // in D-Bus server addresses, as defined by the D-Bus specification at
- // https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
- func EscapeBusAddressValue(val string) string {
- toEsc := strNeedsEscape(val)
- if toEsc == 0 {
- // Avoid unneeded allocation/copying.
- return val
- }
- // Avoid allocation for short paths.
- var buf [64]byte
- var out []byte
- // Every to-be-escaped byte needs 2 extra bytes.
- required := len(val) + 2*toEsc
- if required <= len(buf) {
- out = buf[:required]
- } else {
- out = make([]byte, required)
- }
- j := 0
- for i := 0; i < len(val); i++ {
- if ch := val[i]; needsEscape(ch) {
- // Convert ch to %xx, where xx is hex value.
- out[j] = '%'
- out[j+1] = hexchar(ch >> 4)
- out[j+2] = hexchar(ch & 0x0F)
- j += 3
- } else {
- out[j] = ch
- j++
- }
- }
- return string(out)
- }
- // UnescapeBusAddressValue unescapes values in D-Bus server addresses,
- // as defined by the D-Bus specification at
- // https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
- func UnescapeBusAddressValue(val string) (string, error) {
- // Looks like url.PathUnescape does exactly what is required.
- return url.PathUnescape(val)
- }
- // hexchar returns an octal representation of a n, where n < 16.
- // For invalid values of n, the function panics.
- func hexchar(n byte) byte {
- const hex = "0123456789abcdef"
- // For n >= len(hex), runtime will panic.
- return hex[n]
- }
- // needsEscape tells if a byte is NOT one of optionally-escaped bytes.
- func needsEscape(c byte) bool {
- if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
- return false
- }
- switch c {
- case '-', '_', '/', '\\', '.', '*':
- return false
- }
- return true
- }
- // strNeedsEscape tells how many bytes in the string need escaping.
- func strNeedsEscape(val string) int {
- count := 0
- for i := 0; i < len(val); i++ {
- if needsEscape(val[i]) {
- count++
- }
- }
- return count
- }
|