~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/godbus/dbus/decoder.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package dbus
 
2
 
 
3
import (
 
4
        "encoding/binary"
 
5
        "io"
 
6
        "reflect"
 
7
)
 
8
 
 
9
type 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.
 
17
func 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.
 
25
func (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.
 
37
func (dec *decoder) binread(v interface{}) {
 
38
        if err := binary.Read(dec.in, dec.order, v); err != nil {
 
39
                panic(err)
 
40
        }
 
41
}
 
42
 
 
43
func (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
 
 
67
func (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.
 
224
type FormatError string
 
225
 
 
226
func (e FormatError) Error() string {
 
227
        return "dbus: wire format error: " + string(e)
 
228
}