1package dbus
2
3import (
4	"encoding/binary"
5	"io"
6	"reflect"
7)
8
9type decoder struct {
10	in    io.Reader
11	order binary.ByteOrder
12	pos   int
13}
14
15// newDecoder returns a new decoder that reads values from in. The input is
16// expected to be in the given byte order.
17func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
18	dec := new(decoder)
19	dec.in = in
20	dec.order = order
21	return dec
22}
23
24// align aligns the input to the given boundary and panics on error.
25func (dec *decoder) align(n int) {
26	if dec.pos%n != 0 {
27		newpos := (dec.pos + n - 1) & ^(n - 1)
28		empty := make([]byte, newpos-dec.pos)
29		if _, err := io.ReadFull(dec.in, empty); err != nil {
30			panic(err)
31		}
32		dec.pos = newpos
33	}
34}
35
36// Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
37func (dec *decoder) binread(v interface{}) {
38	if err := binary.Read(dec.in, dec.order, v); err != nil {
39		panic(err)
40	}
41}
42
43func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
44	defer func() {
45		var ok bool
46		v := recover()
47		if err, ok = v.(error); ok {
48			if err == io.EOF || err == io.ErrUnexpectedEOF {
49				err = FormatError("unexpected EOF")
50			}
51		}
52	}()
53	vs = make([]interface{}, 0)
54	s := sig.str
55	for s != "" {
56		err, rem := validSingle(s, 0)
57		if err != nil {
58			return nil, err
59		}
60		v := dec.decode(s[:len(s)-len(rem)], 0)
61		vs = append(vs, v)
62		s = rem
63	}
64	return vs, nil
65}
66
67func (dec *decoder) decode(s string, depth int) interface{} {
68	dec.align(alignment(typeFor(s)))
69	switch s[0] {
70	case 'y':
71		var b [1]byte
72		if _, err := dec.in.Read(b[:]); err != nil {
73			panic(err)
74		}
75		dec.pos++
76		return b[0]
77	case 'b':
78		i := dec.decode("u", depth).(uint32)
79		switch {
80		case i == 0:
81			return false
82		case i == 1:
83			return true
84		default:
85			panic(FormatError("invalid value for boolean"))
86		}
87	case 'n':
88		var i int16
89		dec.binread(&i)
90		dec.pos += 2
91		return i
92	case 'i':
93		var i int32
94		dec.binread(&i)
95		dec.pos += 4
96		return i
97	case 'x':
98		var i int64
99		dec.binread(&i)
100		dec.pos += 8
101		return i
102	case 'q':
103		var i uint16
104		dec.binread(&i)
105		dec.pos += 2
106		return i
107	case 'u':
108		var i uint32
109		dec.binread(&i)
110		dec.pos += 4
111		return i
112	case 't':
113		var i uint64
114		dec.binread(&i)
115		dec.pos += 8
116		return i
117	case 'd':
118		var f float64
119		dec.binread(&f)
120		dec.pos += 8
121		return f
122	case 's':
123		length := dec.decode("u", depth).(uint32)
124		b := make([]byte, int(length)+1)
125		if _, err := io.ReadFull(dec.in, b); err != nil {
126			panic(err)
127		}
128		dec.pos += int(length) + 1
129		return string(b[:len(b)-1])
130	case 'o':
131		return ObjectPath(dec.decode("s", depth).(string))
132	case 'g':
133		length := dec.decode("y", depth).(byte)
134		b := make([]byte, int(length)+1)
135		if _, err := io.ReadFull(dec.in, b); err != nil {
136			panic(err)
137		}
138		dec.pos += int(length) + 1
139		sig, err := ParseSignature(string(b[:len(b)-1]))
140		if err != nil {
141			panic(err)
142		}
143		return sig
144	case 'v':
145		if depth >= 64 {
146			panic(FormatError("input exceeds container depth limit"))
147		}
148		var variant Variant
149		sig := dec.decode("g", depth).(Signature)
150		if len(sig.str) == 0 {
151			panic(FormatError("variant signature is empty"))
152		}
153		err, rem := validSingle(sig.str, 0)
154		if err != nil {
155			panic(err)
156		}
157		if rem != "" {
158			panic(FormatError("variant signature has multiple types"))
159		}
160		variant.sig = sig
161		variant.value = dec.decode(sig.str, depth+1)
162		return variant
163	case 'h':
164		return UnixFDIndex(dec.decode("u", depth).(uint32))
165	case 'a':
166		if len(s) > 1 && s[1] == '{' {
167			ksig := s[2:3]
168			vsig := s[3 : len(s)-1]
169			v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
170			if depth >= 63 {
171				panic(FormatError("input exceeds container depth limit"))
172			}
173			length := dec.decode("u", depth).(uint32)
174			// Even for empty maps, the correct padding must be included
175			dec.align(8)
176			spos := dec.pos
177			for dec.pos < spos+int(length) {
178				dec.align(8)
179				if !isKeyType(v.Type().Key()) {
180					panic(InvalidTypeError{v.Type()})
181				}
182				kv := dec.decode(ksig, depth+2)
183				vv := dec.decode(vsig, depth+2)
184				v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
185			}
186			return v.Interface()
187		}
188		if depth >= 64 {
189			panic(FormatError("input exceeds container depth limit"))
190		}
191		length := dec.decode("u", depth).(uint32)
192		v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
193		// Even for empty arrays, the correct padding must be included
194		dec.align(alignment(typeFor(s[1:])))
195		spos := dec.pos
196		for dec.pos < spos+int(length) {
197			ev := dec.decode(s[1:], depth+1)
198			v = reflect.Append(v, reflect.ValueOf(ev))
199		}
200		return v.Interface()
201	case '(':
202		if depth >= 64 {
203			panic(FormatError("input exceeds container depth limit"))
204		}
205		dec.align(8)
206		v := make([]interface{}, 0)
207		s = s[1 : len(s)-1]
208		for s != "" {
209			err, rem := validSingle(s, 0)
210			if err != nil {
211				panic(err)
212			}
213			ev := dec.decode(s[:len(s)-len(rem)], depth+1)
214			v = append(v, ev)
215			s = rem
216		}
217		return v
218	default:
219		panic(SignatureError{Sig: s})
220	}
221}
222
223// A FormatError is an error in the wire format.
224type FormatError string
225
226func (e FormatError) Error() string {
227	return "dbus: wire format error: " + string(e)
228}
229