123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- package dbus
- import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "reflect"
- "strconv"
- "strings"
- "unicode/utf8"
- )
- type varParser struct {
- tokens []varToken
- i int
- }
- func (p *varParser) backup() {
- p.i--
- }
- func (p *varParser) next() varToken {
- if p.i < len(p.tokens) {
- t := p.tokens[p.i]
- p.i++
- return t
- }
- return varToken{typ: tokEOF}
- }
- type varNode interface {
- Infer() (Signature, error)
- String() string
- Sigs() sigSet
- Value(Signature) (interface{}, error)
- }
- func varMakeNode(p *varParser) (varNode, error) {
- var sig Signature
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokNumber:
- return varMakeNumNode(t, sig)
- case tokString:
- return varMakeStringNode(t, sig)
- case tokBool:
- if sig.str != "" && sig.str != "b" {
- return nil, varTypeError{t.val, sig}
- }
- b, err := strconv.ParseBool(t.val)
- if err != nil {
- return nil, err
- }
- return boolNode(b), nil
- case tokArrayStart:
- return varMakeArrayNode(p, sig)
- case tokVariantStart:
- return varMakeVariantNode(p, sig)
- case tokDictStart:
- return varMakeDictNode(p, sig)
- case tokType:
- if sig.str != "" {
- return nil, errors.New("unexpected type annotation")
- }
- if t.val[0] == '@' {
- sig.str = t.val[1:]
- } else {
- sig.str = varTypeMap[t.val]
- }
- case tokByteString:
- if sig.str != "" && sig.str != "ay" {
- return nil, varTypeError{t.val, sig}
- }
- b, err := varParseByteString(t.val)
- if err != nil {
- return nil, err
- }
- return byteStringNode(b), nil
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
- }
- type varTypeError struct {
- val string
- sig Signature
- }
- func (e varTypeError) Error() string {
- return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
- }
- type sigSet map[Signature]bool
- func (s sigSet) Empty() bool {
- return len(s) == 0
- }
- func (s sigSet) Intersect(s2 sigSet) sigSet {
- r := make(sigSet)
- for k := range s {
- if s2[k] {
- r[k] = true
- }
- }
- return r
- }
- func (s sigSet) Single() (Signature, bool) {
- if len(s) == 1 {
- for k := range s {
- return k, true
- }
- }
- return Signature{}, false
- }
- func (s sigSet) ToArray() sigSet {
- r := make(sigSet, len(s))
- for k := range s {
- r[Signature{"a" + k.str}] = true
- }
- return r
- }
- type numNode struct {
- sig Signature
- str string
- val interface{}
- }
- var numSigSet = sigSet{
- Signature{"y"}: true,
- Signature{"n"}: true,
- Signature{"q"}: true,
- Signature{"i"}: true,
- Signature{"u"}: true,
- Signature{"x"}: true,
- Signature{"t"}: true,
- Signature{"d"}: true,
- }
- func (n numNode) Infer() (Signature, error) {
- if strings.ContainsAny(n.str, ".e") {
- return Signature{"d"}, nil
- }
- return Signature{"i"}, nil
- }
- func (n numNode) String() string {
- return n.str
- }
- func (n numNode) Sigs() sigSet {
- if n.sig.str != "" {
- return sigSet{n.sig: true}
- }
- if strings.ContainsAny(n.str, ".e") {
- return sigSet{Signature{"d"}: true}
- }
- return numSigSet
- }
- func (n numNode) Value(sig Signature) (interface{}, error) {
- if n.sig.str != "" && n.sig != sig {
- return nil, varTypeError{n.str, sig}
- }
- if n.val != nil {
- return n.val, nil
- }
- return varNumAs(n.str, sig)
- }
- func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
- if sig.str == "" {
- return numNode{str: tok.val}, nil
- }
- num, err := varNumAs(tok.val, sig)
- if err != nil {
- return nil, err
- }
- return numNode{sig: sig, val: num}, nil
- }
- func varNumAs(s string, sig Signature) (interface{}, error) {
- isUnsigned := false
- size := 32
- switch sig.str {
- case "n":
- size = 16
- case "i":
- case "x":
- size = 64
- case "y":
- size = 8
- isUnsigned = true
- case "q":
- size = 16
- isUnsigned = true
- case "u":
- isUnsigned = true
- case "t":
- size = 64
- isUnsigned = true
- case "d":
- d, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, err
- }
- return d, nil
- default:
- return nil, varTypeError{s, sig}
- }
- base := 10
- if strings.HasPrefix(s, "0x") {
- base = 16
- s = s[2:]
- }
- if strings.HasPrefix(s, "0") && len(s) != 1 {
- base = 8
- s = s[1:]
- }
- if isUnsigned {
- i, err := strconv.ParseUint(s, base, size)
- if err != nil {
- return nil, err
- }
- var v interface{} = i
- switch sig.str {
- case "y":
- v = byte(i)
- case "q":
- v = uint16(i)
- case "u":
- v = uint32(i)
- }
- return v, nil
- }
- i, err := strconv.ParseInt(s, base, size)
- if err != nil {
- return nil, err
- }
- var v interface{} = i
- switch sig.str {
- case "n":
- v = int16(i)
- case "i":
- v = int32(i)
- }
- return v, nil
- }
- type stringNode struct {
- sig Signature
- str string // parsed
- val interface{} // has correct type
- }
- var stringSigSet = sigSet{
- Signature{"s"}: true,
- Signature{"g"}: true,
- Signature{"o"}: true,
- }
- func (n stringNode) Infer() (Signature, error) {
- return Signature{"s"}, nil
- }
- func (n stringNode) String() string {
- return n.str
- }
- func (n stringNode) Sigs() sigSet {
- if n.sig.str != "" {
- return sigSet{n.sig: true}
- }
- return stringSigSet
- }
- func (n stringNode) Value(sig Signature) (interface{}, error) {
- if n.sig.str != "" && n.sig != sig {
- return nil, varTypeError{n.str, sig}
- }
- if n.val != nil {
- return n.val, nil
- }
- switch {
- case sig.str == "g":
- return Signature{n.str}, nil
- case sig.str == "o":
- return ObjectPath(n.str), nil
- case sig.str == "s":
- return n.str, nil
- default:
- return nil, varTypeError{n.str, sig}
- }
- }
- func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
- if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
- return nil, fmt.Errorf("invalid type %q for string", sig.str)
- }
- s, err := varParseString(tok.val)
- if err != nil {
- return nil, err
- }
- n := stringNode{str: s}
- if sig.str == "" {
- return stringNode{str: s}, nil
- }
- n.sig = sig
- switch sig.str {
- case "o":
- n.val = ObjectPath(s)
- case "g":
- n.val = Signature{s}
- case "s":
- n.val = s
- }
- return n, nil
- }
- func varParseString(s string) (string, error) {
- // quotes are guaranteed to be there
- s = s[1 : len(s)-1]
- buf := new(bytes.Buffer)
- for len(s) != 0 {
- r, size := utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && size == 1 {
- return "", errors.New("invalid UTF-8")
- }
- s = s[size:]
- if r != '\\' {
- buf.WriteRune(r)
- continue
- }
- r, size = utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && size == 1 {
- return "", errors.New("invalid UTF-8")
- }
- s = s[size:]
- switch r {
- case 'a':
- buf.WriteRune(0x7)
- case 'b':
- buf.WriteRune(0x8)
- case 'f':
- buf.WriteRune(0xc)
- case 'n':
- buf.WriteRune('\n')
- case 'r':
- buf.WriteRune('\r')
- case 't':
- buf.WriteRune('\t')
- case '\n':
- case 'u':
- if len(s) < 4 {
- return "", errors.New("short unicode escape")
- }
- r, err := strconv.ParseUint(s[:4], 16, 32)
- if err != nil {
- return "", err
- }
- buf.WriteRune(rune(r))
- s = s[4:]
- case 'U':
- if len(s) < 8 {
- return "", errors.New("short unicode escape")
- }
- r, err := strconv.ParseUint(s[:8], 16, 32)
- if err != nil {
- return "", err
- }
- buf.WriteRune(rune(r))
- s = s[8:]
- default:
- buf.WriteRune(r)
- }
- }
- return buf.String(), nil
- }
- var boolSigSet = sigSet{Signature{"b"}: true}
- type boolNode bool
- func (boolNode) Infer() (Signature, error) {
- return Signature{"b"}, nil
- }
- func (b boolNode) String() string {
- if b {
- return "true"
- }
- return "false"
- }
- func (boolNode) Sigs() sigSet {
- return boolSigSet
- }
- func (b boolNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "b" {
- return nil, varTypeError{b.String(), sig}
- }
- return bool(b), nil
- }
- type arrayNode struct {
- set sigSet
- children []varNode
- val interface{}
- }
- func (n arrayNode) Infer() (Signature, error) {
- for _, v := range n.children {
- csig, err := varInfer(v)
- if err != nil {
- continue
- }
- return Signature{"a" + csig.str}, nil
- }
- return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
- }
- func (n arrayNode) String() string {
- s := "["
- for i, v := range n.children {
- s += v.String()
- if i != len(n.children)-1 {
- s += ", "
- }
- }
- return s + "]"
- }
- func (n arrayNode) Sigs() sigSet {
- return n.set
- }
- func (n arrayNode) Value(sig Signature) (interface{}, error) {
- if n.set.Empty() {
- // no type information whatsoever, so this must be an empty slice
- return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
- }
- if !n.set[sig] {
- return nil, varTypeError{n.String(), sig}
- }
- s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
- for i, v := range n.children {
- rv, err := v.Value(Signature{sig.str[1:]})
- if err != nil {
- return nil, err
- }
- s.Index(i).Set(reflect.ValueOf(rv))
- }
- return s.Interface(), nil
- }
- func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
- var n arrayNode
- if sig.str != "" {
- n.set = sigSet{sig: true}
- }
- if t := p.next(); t.typ == tokArrayEnd {
- return n, nil
- } else {
- p.backup()
- }
- Loop:
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- cn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if cset := cn.Sigs(); !cset.Empty() {
- if n.set.Empty() {
- n.set = cset.ToArray()
- } else {
- nset := cset.ToArray().Intersect(n.set)
- if nset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
- }
- n.set = nset
- }
- }
- n.children = append(n.children, cn)
- switch t := p.next(); t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokArrayEnd:
- break Loop
- case tokComma:
- continue
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
- return n, nil
- }
- type variantNode struct {
- n varNode
- }
- var variantSet = sigSet{
- Signature{"v"}: true,
- }
- func (variantNode) Infer() (Signature, error) {
- return Signature{"v"}, nil
- }
- func (n variantNode) String() string {
- return "<" + n.n.String() + ">"
- }
- func (variantNode) Sigs() sigSet {
- return variantSet
- }
- func (n variantNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "v" {
- return nil, varTypeError{n.String(), sig}
- }
- sig, err := varInfer(n.n)
- if err != nil {
- return nil, err
- }
- v, err := n.n.Value(sig)
- if err != nil {
- return nil, err
- }
- return MakeVariant(v), nil
- }
- func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
- n, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if t := p.next(); t.typ != tokVariantEnd {
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- vn := variantNode{n}
- if sig.str != "" && sig.str != "v" {
- return nil, varTypeError{vn.String(), sig}
- }
- return variantNode{n}, nil
- }
- type dictEntry struct {
- key, val varNode
- }
- type dictNode struct {
- kset, vset sigSet
- children []dictEntry
- val interface{}
- }
- func (n dictNode) Infer() (Signature, error) {
- for _, v := range n.children {
- ksig, err := varInfer(v.key)
- if err != nil {
- continue
- }
- vsig, err := varInfer(v.val)
- if err != nil {
- continue
- }
- return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
- }
- return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
- }
- func (n dictNode) String() string {
- s := "{"
- for i, v := range n.children {
- s += v.key.String() + ": " + v.val.String()
- if i != len(n.children)-1 {
- s += ", "
- }
- }
- return s + "}"
- }
- func (n dictNode) Sigs() sigSet {
- r := sigSet{}
- for k := range n.kset {
- for v := range n.vset {
- sig := "a{" + k.str + v.str + "}"
- r[Signature{sig}] = true
- }
- }
- return r
- }
- func (n dictNode) Value(sig Signature) (interface{}, error) {
- set := n.Sigs()
- if set.Empty() {
- // no type information -> empty dict
- return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
- }
- if !set[sig] {
- return nil, varTypeError{n.String(), sig}
- }
- m := reflect.MakeMap(typeFor(sig.str))
- ksig := Signature{sig.str[2:3]}
- vsig := Signature{sig.str[3 : len(sig.str)-1]}
- for _, v := range n.children {
- kv, err := v.key.Value(ksig)
- if err != nil {
- return nil, err
- }
- vv, err := v.val.Value(vsig)
- if err != nil {
- return nil, err
- }
- m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
- }
- return m.Interface(), nil
- }
- func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
- var n dictNode
- if sig.str != "" {
- if len(sig.str) < 5 {
- return nil, fmt.Errorf("invalid signature %q for dict type", sig)
- }
- ksig := Signature{string(sig.str[2])}
- vsig := Signature{sig.str[3 : len(sig.str)-1]}
- n.kset = sigSet{ksig: true}
- n.vset = sigSet{vsig: true}
- }
- if t := p.next(); t.typ == tokDictEnd {
- return n, nil
- } else {
- p.backup()
- }
- Loop:
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- kn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if kset := kn.Sigs(); !kset.Empty() {
- if n.kset.Empty() {
- n.kset = kset
- } else {
- n.kset = kset.Intersect(n.kset)
- if n.kset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
- }
- }
- }
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokColon:
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- vn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if vset := vn.Sigs(); !vset.Empty() {
- if n.vset.Empty() {
- n.vset = vset
- } else {
- n.vset = n.vset.Intersect(vset)
- if n.vset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
- }
- }
- }
- n.children = append(n.children, dictEntry{kn, vn})
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokDictEnd:
- break Loop
- case tokComma:
- continue
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
- return n, nil
- }
- type byteStringNode []byte
- var byteStringSet = sigSet{
- Signature{"ay"}: true,
- }
- func (byteStringNode) Infer() (Signature, error) {
- return Signature{"ay"}, nil
- }
- func (b byteStringNode) String() string {
- return string(b)
- }
- func (b byteStringNode) Sigs() sigSet {
- return byteStringSet
- }
- func (b byteStringNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "ay" {
- return nil, varTypeError{b.String(), sig}
- }
- return []byte(b), nil
- }
- func varParseByteString(s string) ([]byte, error) {
- // quotes and b at start are guaranteed to be there
- b := make([]byte, 0, 1)
- s = s[2 : len(s)-1]
- for len(s) != 0 {
- c := s[0]
- s = s[1:]
- if c != '\\' {
- b = append(b, c)
- continue
- }
- c = s[0]
- s = s[1:]
- switch c {
- case 'a':
- b = append(b, 0x7)
- case 'b':
- b = append(b, 0x8)
- case 'f':
- b = append(b, 0xc)
- case 'n':
- b = append(b, '\n')
- case 'r':
- b = append(b, '\r')
- case 't':
- b = append(b, '\t')
- case 'x':
- if len(s) < 2 {
- return nil, errors.New("short escape")
- }
- n, err := strconv.ParseUint(s[:2], 16, 8)
- if err != nil {
- return nil, err
- }
- b = append(b, byte(n))
- s = s[2:]
- case '0':
- if len(s) < 3 {
- return nil, errors.New("short escape")
- }
- n, err := strconv.ParseUint(s[:3], 8, 8)
- if err != nil {
- return nil, err
- }
- b = append(b, byte(n))
- s = s[3:]
- default:
- b = append(b, c)
- }
- }
- return append(b, 0), nil
- }
- func varInfer(n varNode) (Signature, error) {
- if sig, ok := n.Sigs().Single(); ok {
- return sig, nil
- }
- return n.Infer()
- }
|