123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- package dbus
- import (
- "encoding/binary"
- "io"
- "reflect"
- )
- type decoder struct {
- in io.Reader
- order binary.ByteOrder
- pos int
- }
- // newDecoder returns a new decoder that reads values from in. The input is
- // expected to be in the given byte order.
- func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
- dec := new(decoder)
- dec.in = in
- dec.order = order
- return dec
- }
- // align aligns the input to the given boundary and panics on error.
- func (dec *decoder) align(n int) {
- if dec.pos%n != 0 {
- newpos := (dec.pos + n - 1) & ^(n - 1)
- empty := make([]byte, newpos-dec.pos)
- if _, err := io.ReadFull(dec.in, empty); err != nil {
- panic(err)
- }
- dec.pos = newpos
- }
- }
- // Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
- func (dec *decoder) binread(v interface{}) {
- if err := binary.Read(dec.in, dec.order, v); err != nil {
- panic(err)
- }
- }
- func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
- defer func() {
- var ok bool
- v := recover()
- if err, ok = v.(error); ok {
- if err == io.EOF || err == io.ErrUnexpectedEOF {
- err = FormatError("unexpected EOF")
- }
- }
- }()
- vs = make([]interface{}, 0)
- s := sig.str
- for s != "" {
- err, rem := validSingle(s, 0)
- if err != nil {
- return nil, err
- }
- v := dec.decode(s[:len(s)-len(rem)], 0)
- vs = append(vs, v)
- s = rem
- }
- return vs, nil
- }
- func (dec *decoder) decode(s string, depth int) interface{} {
- dec.align(alignment(typeFor(s)))
- switch s[0] {
- case 'y':
- var b [1]byte
- if _, err := dec.in.Read(b[:]); err != nil {
- panic(err)
- }
- dec.pos++
- return b[0]
- case 'b':
- i := dec.decode("u", depth).(uint32)
- switch {
- case i == 0:
- return false
- case i == 1:
- return true
- default:
- panic(FormatError("invalid value for boolean"))
- }
- case 'n':
- var i int16
- dec.binread(&i)
- dec.pos += 2
- return i
- case 'i':
- var i int32
- dec.binread(&i)
- dec.pos += 4
- return i
- case 'x':
- var i int64
- dec.binread(&i)
- dec.pos += 8
- return i
- case 'q':
- var i uint16
- dec.binread(&i)
- dec.pos += 2
- return i
- case 'u':
- var i uint32
- dec.binread(&i)
- dec.pos += 4
- return i
- case 't':
- var i uint64
- dec.binread(&i)
- dec.pos += 8
- return i
- case 'd':
- var f float64
- dec.binread(&f)
- dec.pos += 8
- return f
- case 's':
- length := dec.decode("u", depth).(uint32)
- b := make([]byte, int(length)+1)
- if _, err := io.ReadFull(dec.in, b); err != nil {
- panic(err)
- }
- dec.pos += int(length) + 1
- return string(b[:len(b)-1])
- case 'o':
- return ObjectPath(dec.decode("s", depth).(string))
- case 'g':
- length := dec.decode("y", depth).(byte)
- b := make([]byte, int(length)+1)
- if _, err := io.ReadFull(dec.in, b); err != nil {
- panic(err)
- }
- dec.pos += int(length) + 1
- sig, err := ParseSignature(string(b[:len(b)-1]))
- if err != nil {
- panic(err)
- }
- return sig
- case 'v':
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- var variant Variant
- sig := dec.decode("g", depth).(Signature)
- if len(sig.str) == 0 {
- panic(FormatError("variant signature is empty"))
- }
- err, rem := validSingle(sig.str, 0)
- if err != nil {
- panic(err)
- }
- if rem != "" {
- panic(FormatError("variant signature has multiple types"))
- }
- variant.sig = sig
- variant.value = dec.decode(sig.str, depth+1)
- return variant
- case 'h':
- return UnixFDIndex(dec.decode("u", depth).(uint32))
- case 'a':
- if len(s) > 1 && s[1] == '{' {
- ksig := s[2:3]
- vsig := s[3 : len(s)-1]
- v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
- if depth >= 63 {
- panic(FormatError("input exceeds container depth limit"))
- }
- length := dec.decode("u", depth).(uint32)
- // Even for empty maps, the correct padding must be included
- dec.align(8)
- spos := dec.pos
- for dec.pos < spos+int(length) {
- dec.align(8)
- if !isKeyType(v.Type().Key()) {
- panic(InvalidTypeError{v.Type()})
- }
- kv := dec.decode(ksig, depth+2)
- vv := dec.decode(vsig, depth+2)
- v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
- }
- return v.Interface()
- }
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- length := dec.decode("u", depth).(uint32)
- v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
- // Even for empty arrays, the correct padding must be included
- dec.align(alignment(typeFor(s[1:])))
- spos := dec.pos
- for dec.pos < spos+int(length) {
- ev := dec.decode(s[1:], depth+1)
- v = reflect.Append(v, reflect.ValueOf(ev))
- }
- return v.Interface()
- case '(':
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- dec.align(8)
- v := make([]interface{}, 0)
- s = s[1 : len(s)-1]
- for s != "" {
- err, rem := validSingle(s, 0)
- if err != nil {
- panic(err)
- }
- ev := dec.decode(s[:len(s)-len(rem)], depth+1)
- v = append(v, ev)
- s = rem
- }
- return v
- default:
- panic(SignatureError{Sig: s})
- }
- }
- // A FormatError is an error in the wire format.
- type FormatError string
- func (e FormatError) Error() string {
- return "dbus: wire format error: " + string(e)
- }
|