aboutsummaryrefslogtreecommitdiffhomepage
path: root/dbus/address.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-07-02 21:52:07 +0900
committerOphestra <cat@gensokyo.uk>2025-07-02 21:52:07 +0900
commit82561d62b66f17c05604e87f18187bb3a91f00d2 (patch)
treec1543f85b4458b7d5cb2cf7b1baa9dee318debfe /dbus/address.go
parenteec021cc4b4eb42bc9c8311755826828bfba1996 (diff)
system: move system access packages
These packages loosely belong in the "system" package and "system" provides high level wrappers for all of them. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'dbus/address.go')
-rw-r--r--dbus/address.go186
1 files changed, 0 insertions, 186 deletions
diff --git a/dbus/address.go b/dbus/address.go
deleted file mode 100644
index bec49e62..00000000
--- a/dbus/address.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package dbus
-
-import (
- "bytes"
- "encoding/hex"
- "errors"
- "fmt"
- "slices"
-)
-
-type AddrEntry struct {
- Method string `json:"method"`
- Values [][2]string `json:"values"`
-}
-
-// Parse parses D-Bus address according to
-// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses
-func Parse(addr []byte) ([]AddrEntry, error) {
- // Look for a semicolon
- address := bytes.Split(bytes.TrimSuffix(addr, []byte{';'}), []byte{';'})
-
- // Allocate for entries
- v := make([]AddrEntry, len(address))
-
- for i, s := range address {
- var pairs [][]byte
-
- // Look for the colon :
- if method, list, ok := bytes.Cut(s, []byte{':'}); !ok {
- return v, &BadAddressError{ErrNoColon, i, s, -1, nil}
- } else {
- pairs = bytes.Split(list, []byte{','})
- v[i].Method = string(method)
- v[i].Values = make([][2]string, len(pairs))
- }
-
- for j, pair := range pairs {
- key, value, ok := bytes.Cut(pair, []byte{'='})
- if !ok {
- return v, &BadAddressError{ErrBadPairSep, i, s, j, pair}
- }
- if len(key) == 0 {
- return v, &BadAddressError{ErrBadPairKey, i, s, j, pair}
- }
- if len(value) == 0 {
- return v, &BadAddressError{ErrBadPairVal, i, s, j, pair}
- }
- v[i].Values[j][0] = string(key)
-
- if val, errno := unescapeValue(value); errno != errSuccess {
- return v, &BadAddressError{errno, i, s, j, pair}
- } else {
- v[i].Values[j][1] = string(val)
- }
- }
- }
-
- return v, nil
-}
-
-func unescapeValue(v []byte) (val []byte, errno ParseError) {
- if l := len(v) - (bytes.Count(v, []byte{'%'}) * 2); l < 0 {
- errno = ErrBadValLength
- return
- } else {
- val = make([]byte, l)
- }
-
- var i, skip int
- for iu, b := range v {
- if skip > 0 {
- skip--
- continue
- }
-
- if ib := bytes.IndexByte([]byte("-_/.\\*"), b); ib != -1 { // - // _/.\*
- goto opt
- } else if b >= '0' && b <= '9' { // 0-9
- goto opt
- } else if b >= 'A' && b <= 'Z' { // A-Z
- goto opt
- } else if b >= 'a' && b <= 'z' { // a-z
- goto opt
- }
-
- if b != '%' {
- errno = ErrBadValByte
- break
- }
-
- skip += 2
- if iu+2 >= len(v) {
- errno = ErrBadValHexLength
- break
- }
- if c, err := hex.Decode(val[i:i+1], v[iu+1:iu+3]); err != nil {
- if errors.As(err, new(hex.InvalidByteError)) {
- errno = ErrBadValHexByte
- break
- }
- // unreachable
- panic(err.Error())
- } else if c != 1 {
- // unreachable
- panic(fmt.Sprintf("invalid decode length %d", c))
- }
- i++
- continue
-
- opt:
- val[i] = b
- i++
- }
-
- return
-}
-
-type ParseError uint8
-
-func (e ParseError) Error() string {
- switch e {
- case errSuccess:
- panic("attempted to return success as error")
- case ErrNoColon:
- return "address does not contain a colon"
- case ErrBadPairSep:
- return "'=' character not found"
- case ErrBadPairKey:
- return "'=' character has no key preceding it"
- case ErrBadPairVal:
- return "'=' character has no value following it"
- case ErrBadValLength:
- return "unescaped value has impossible length"
- case ErrBadValByte:
- return "in D-Bus address, characters other than [-0-9A-Za-z_/.\\*] should have been escaped"
- case ErrBadValHexLength:
- return "in D-Bus address, percent character was not followed by two hex digits"
- case ErrBadValHexByte:
- return "in D-Bus address, percent character was followed by characters other than hex digits"
-
- default:
- return fmt.Sprintf("parse error %d", e)
- }
-}
-
-const (
- errSuccess ParseError = iota
- ErrNoColon
- ErrBadPairSep
- ErrBadPairKey
- ErrBadPairVal
- ErrBadValLength
- ErrBadValByte
- ErrBadValHexLength
- ErrBadValHexByte
-)
-
-type BadAddressError struct {
- // error type
- Type ParseError
-
- // bad entry position
- EntryPos int
- // bad entry value
- EntryVal []byte
-
- // bad pair position
- PairPos int
- // bad pair value
- PairVal []byte
-}
-
-func (a *BadAddressError) Is(err error) bool {
- var b *BadAddressError
- return errors.As(err, &b) && a.Type == b.Type &&
- a.EntryPos == b.EntryPos && slices.Equal(a.EntryVal, b.EntryVal) &&
- a.PairPos == b.PairPos && slices.Equal(a.PairVal, b.PairVal)
-}
-
-func (a *BadAddressError) Error() string {
- return a.Type.Error()
-}
-
-func (a *BadAddressError) Unwrap() error {
- return a.Type
-}