~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/godbus/dbus/variant_parser.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
        "bytes"
 
5
        "errors"
 
6
        "fmt"
 
7
        "io"
 
8
        "reflect"
 
9
        "strconv"
 
10
        "strings"
 
11
        "unicode/utf8"
 
12
)
 
13
 
 
14
type varParser struct {
 
15
        tokens []varToken
 
16
        i      int
 
17
}
 
18
 
 
19
func (p *varParser) backup() {
 
20
        p.i--
 
21
}
 
22
 
 
23
func (p *varParser) next() varToken {
 
24
        if p.i < len(p.tokens) {
 
25
                t := p.tokens[p.i]
 
26
                p.i++
 
27
                return t
 
28
        }
 
29
        return varToken{typ: tokEOF}
 
30
}
 
31
 
 
32
type varNode interface {
 
33
        Infer() (Signature, error)
 
34
        String() string
 
35
        Sigs() sigSet
 
36
        Value(Signature) (interface{}, error)
 
37
}
 
38
 
 
39
func varMakeNode(p *varParser) (varNode, error) {
 
40
        var sig Signature
 
41
 
 
42
        for {
 
43
                t := p.next()
 
44
                switch t.typ {
 
45
                case tokEOF:
 
46
                        return nil, io.ErrUnexpectedEOF
 
47
                case tokError:
 
48
                        return nil, errors.New(t.val)
 
49
                case tokNumber:
 
50
                        return varMakeNumNode(t, sig)
 
51
                case tokString:
 
52
                        return varMakeStringNode(t, sig)
 
53
                case tokBool:
 
54
                        if sig.str != "" && sig.str != "b" {
 
55
                                return nil, varTypeError{t.val, sig}
 
56
                        }
 
57
                        b, err := strconv.ParseBool(t.val)
 
58
                        if err != nil {
 
59
                                return nil, err
 
60
                        }
 
61
                        return boolNode(b), nil
 
62
                case tokArrayStart:
 
63
                        return varMakeArrayNode(p, sig)
 
64
                case tokVariantStart:
 
65
                        return varMakeVariantNode(p, sig)
 
66
                case tokDictStart:
 
67
                        return varMakeDictNode(p, sig)
 
68
                case tokType:
 
69
                        if sig.str != "" {
 
70
                                return nil, errors.New("unexpected type annotation")
 
71
                        }
 
72
                        if t.val[0] == '@' {
 
73
                                sig.str = t.val[1:]
 
74
                        } else {
 
75
                                sig.str = varTypeMap[t.val]
 
76
                        }
 
77
                case tokByteString:
 
78
                        if sig.str != "" && sig.str != "ay" {
 
79
                                return nil, varTypeError{t.val, sig}
 
80
                        }
 
81
                        b, err := varParseByteString(t.val)
 
82
                        if err != nil {
 
83
                                return nil, err
 
84
                        }
 
85
                        return byteStringNode(b), nil
 
86
                default:
 
87
                        return nil, fmt.Errorf("unexpected %q", t.val)
 
88
                }
 
89
        }
 
90
}
 
91
 
 
92
type varTypeError struct {
 
93
        val string
 
94
        sig Signature
 
95
}
 
96
 
 
97
func (e varTypeError) Error() string {
 
98
        return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
 
99
}
 
100
 
 
101
type sigSet map[Signature]bool
 
102
 
 
103
func (s sigSet) Empty() bool {
 
104
        return len(s) == 0
 
105
}
 
106
 
 
107
func (s sigSet) Intersect(s2 sigSet) sigSet {
 
108
        r := make(sigSet)
 
109
        for k := range s {
 
110
                if s2[k] {
 
111
                        r[k] = true
 
112
                }
 
113
        }
 
114
        return r
 
115
}
 
116
 
 
117
func (s sigSet) Single() (Signature, bool) {
 
118
        if len(s) == 1 {
 
119
                for k := range s {
 
120
                        return k, true
 
121
                }
 
122
        }
 
123
        return Signature{}, false
 
124
}
 
125
 
 
126
func (s sigSet) ToArray() sigSet {
 
127
        r := make(sigSet, len(s))
 
128
        for k := range s {
 
129
                r[Signature{"a" + k.str}] = true
 
130
        }
 
131
        return r
 
132
}
 
133
 
 
134
type numNode struct {
 
135
        sig Signature
 
136
        str string
 
137
        val interface{}
 
138
}
 
139
 
 
140
var numSigSet = sigSet{
 
141
        Signature{"y"}: true,
 
142
        Signature{"n"}: true,
 
143
        Signature{"q"}: true,
 
144
        Signature{"i"}: true,
 
145
        Signature{"u"}: true,
 
146
        Signature{"x"}: true,
 
147
        Signature{"t"}: true,
 
148
        Signature{"d"}: true,
 
149
}
 
150
 
 
151
func (n numNode) Infer() (Signature, error) {
 
152
        if strings.ContainsAny(n.str, ".e") {
 
153
                return Signature{"d"}, nil
 
154
        }
 
155
        return Signature{"i"}, nil
 
156
}
 
157
 
 
158
func (n numNode) String() string {
 
159
        return n.str
 
160
}
 
161
 
 
162
func (n numNode) Sigs() sigSet {
 
163
        if n.sig.str != "" {
 
164
                return sigSet{n.sig: true}
 
165
        }
 
166
        if strings.ContainsAny(n.str, ".e") {
 
167
                return sigSet{Signature{"d"}: true}
 
168
        }
 
169
        return numSigSet
 
170
}
 
171
 
 
172
func (n numNode) Value(sig Signature) (interface{}, error) {
 
173
        if n.sig.str != "" && n.sig != sig {
 
174
                return nil, varTypeError{n.str, sig}
 
175
        }
 
176
        if n.val != nil {
 
177
                return n.val, nil
 
178
        }
 
179
        return varNumAs(n.str, sig)
 
180
}
 
181
 
 
182
func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
 
183
        if sig.str == "" {
 
184
                return numNode{str: tok.val}, nil
 
185
        }
 
186
        num, err := varNumAs(tok.val, sig)
 
187
        if err != nil {
 
188
                return nil, err
 
189
        }
 
190
        return numNode{sig: sig, val: num}, nil
 
191
}
 
192
 
 
193
func varNumAs(s string, sig Signature) (interface{}, error) {
 
194
        isUnsigned := false
 
195
        size := 32
 
196
        switch sig.str {
 
197
        case "n":
 
198
                size = 16
 
199
        case "i":
 
200
        case "x":
 
201
                size = 64
 
202
        case "y":
 
203
                size = 8
 
204
                isUnsigned = true
 
205
        case "q":
 
206
                size = 16
 
207
                isUnsigned = true
 
208
        case "u":
 
209
                isUnsigned = true
 
210
        case "t":
 
211
                size = 64
 
212
                isUnsigned = true
 
213
        case "d":
 
214
                d, err := strconv.ParseFloat(s, 64)
 
215
                if err != nil {
 
216
                        return nil, err
 
217
                }
 
218
                return d, nil
 
219
        default:
 
220
                return nil, varTypeError{s, sig}
 
221
        }
 
222
        base := 10
 
223
        if strings.HasPrefix(s, "0x") {
 
224
                base = 16
 
225
                s = s[2:]
 
226
        }
 
227
        if strings.HasPrefix(s, "0") && len(s) != 1 {
 
228
                base = 8
 
229
                s = s[1:]
 
230
        }
 
231
        if isUnsigned {
 
232
                i, err := strconv.ParseUint(s, base, size)
 
233
                if err != nil {
 
234
                        return nil, err
 
235
                }
 
236
                var v interface{} = i
 
237
                switch sig.str {
 
238
                case "y":
 
239
                        v = byte(i)
 
240
                case "q":
 
241
                        v = uint16(i)
 
242
                case "u":
 
243
                        v = uint32(i)
 
244
                }
 
245
                return v, nil
 
246
        }
 
247
        i, err := strconv.ParseInt(s, base, size)
 
248
        if err != nil {
 
249
                return nil, err
 
250
        }
 
251
        var v interface{} = i
 
252
        switch sig.str {
 
253
        case "n":
 
254
                v = int16(i)
 
255
        case "i":
 
256
                v = int32(i)
 
257
        }
 
258
        return v, nil
 
259
}
 
260
 
 
261
type stringNode struct {
 
262
        sig Signature
 
263
        str string      // parsed
 
264
        val interface{} // has correct type
 
265
}
 
266
 
 
267
var stringSigSet = sigSet{
 
268
        Signature{"s"}: true,
 
269
        Signature{"g"}: true,
 
270
        Signature{"o"}: true,
 
271
}
 
272
 
 
273
func (n stringNode) Infer() (Signature, error) {
 
274
        return Signature{"s"}, nil
 
275
}
 
276
 
 
277
func (n stringNode) String() string {
 
278
        return n.str
 
279
}
 
280
 
 
281
func (n stringNode) Sigs() sigSet {
 
282
        if n.sig.str != "" {
 
283
                return sigSet{n.sig: true}
 
284
        }
 
285
        return stringSigSet
 
286
}
 
287
 
 
288
func (n stringNode) Value(sig Signature) (interface{}, error) {
 
289
        if n.sig.str != "" && n.sig != sig {
 
290
                return nil, varTypeError{n.str, sig}
 
291
        }
 
292
        if n.val != nil {
 
293
                return n.val, nil
 
294
        }
 
295
        switch {
 
296
        case sig.str == "g":
 
297
                return Signature{n.str}, nil
 
298
        case sig.str == "o":
 
299
                return ObjectPath(n.str), nil
 
300
        case sig.str == "s":
 
301
                return n.str, nil
 
302
        default:
 
303
                return nil, varTypeError{n.str, sig}
 
304
        }
 
305
}
 
306
 
 
307
func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
 
308
        if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
 
309
                return nil, fmt.Errorf("invalid type %q for string", sig.str)
 
310
        }
 
311
        s, err := varParseString(tok.val)
 
312
        if err != nil {
 
313
                return nil, err
 
314
        }
 
315
        n := stringNode{str: s}
 
316
        if sig.str == "" {
 
317
                return stringNode{str: s}, nil
 
318
        }
 
319
        n.sig = sig
 
320
        switch sig.str {
 
321
        case "o":
 
322
                n.val = ObjectPath(s)
 
323
        case "g":
 
324
                n.val = Signature{s}
 
325
        case "s":
 
326
                n.val = s
 
327
        }
 
328
        return n, nil
 
329
}
 
330
 
 
331
func varParseString(s string) (string, error) {
 
332
        // quotes are guaranteed to be there
 
333
        s = s[1 : len(s)-1]
 
334
        buf := new(bytes.Buffer)
 
335
        for len(s) != 0 {
 
336
                r, size := utf8.DecodeRuneInString(s)
 
337
                if r == utf8.RuneError && size == 1 {
 
338
                        return "", errors.New("invalid UTF-8")
 
339
                }
 
340
                s = s[size:]
 
341
                if r != '\\' {
 
342
                        buf.WriteRune(r)
 
343
                        continue
 
344
                }
 
345
                r, size = utf8.DecodeRuneInString(s)
 
346
                if r == utf8.RuneError && size == 1 {
 
347
                        return "", errors.New("invalid UTF-8")
 
348
                }
 
349
                s = s[size:]
 
350
                switch r {
 
351
                case 'a':
 
352
                        buf.WriteRune(0x7)
 
353
                case 'b':
 
354
                        buf.WriteRune(0x8)
 
355
                case 'f':
 
356
                        buf.WriteRune(0xc)
 
357
                case 'n':
 
358
                        buf.WriteRune('\n')
 
359
                case 'r':
 
360
                        buf.WriteRune('\r')
 
361
                case 't':
 
362
                        buf.WriteRune('\t')
 
363
                case '\n':
 
364
                case 'u':
 
365
                        if len(s) < 4 {
 
366
                                return "", errors.New("short unicode escape")
 
367
                        }
 
368
                        r, err := strconv.ParseUint(s[:4], 16, 32)
 
369
                        if err != nil {
 
370
                                return "", err
 
371
                        }
 
372
                        buf.WriteRune(rune(r))
 
373
                        s = s[4:]
 
374
                case 'U':
 
375
                        if len(s) < 8 {
 
376
                                return "", errors.New("short unicode escape")
 
377
                        }
 
378
                        r, err := strconv.ParseUint(s[:8], 16, 32)
 
379
                        if err != nil {
 
380
                                return "", err
 
381
                        }
 
382
                        buf.WriteRune(rune(r))
 
383
                        s = s[8:]
 
384
                default:
 
385
                        buf.WriteRune(r)
 
386
                }
 
387
        }
 
388
        return buf.String(), nil
 
389
}
 
390
 
 
391
var boolSigSet = sigSet{Signature{"b"}: true}
 
392
 
 
393
type boolNode bool
 
394
 
 
395
func (boolNode) Infer() (Signature, error) {
 
396
        return Signature{"b"}, nil
 
397
}
 
398
 
 
399
func (b boolNode) String() string {
 
400
        if b {
 
401
                return "true"
 
402
        }
 
403
        return "false"
 
404
}
 
405
 
 
406
func (boolNode) Sigs() sigSet {
 
407
        return boolSigSet
 
408
}
 
409
 
 
410
func (b boolNode) Value(sig Signature) (interface{}, error) {
 
411
        if sig.str != "b" {
 
412
                return nil, varTypeError{b.String(), sig}
 
413
        }
 
414
        return bool(b), nil
 
415
}
 
416
 
 
417
type arrayNode struct {
 
418
        set      sigSet
 
419
        children []varNode
 
420
        val      interface{}
 
421
}
 
422
 
 
423
func (n arrayNode) Infer() (Signature, error) {
 
424
        for _, v := range n.children {
 
425
                csig, err := varInfer(v)
 
426
                if err != nil {
 
427
                        continue
 
428
                }
 
429
                return Signature{"a" + csig.str}, nil
 
430
        }
 
431
        return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
 
432
}
 
433
 
 
434
func (n arrayNode) String() string {
 
435
        s := "["
 
436
        for i, v := range n.children {
 
437
                s += v.String()
 
438
                if i != len(n.children)-1 {
 
439
                        s += ", "
 
440
                }
 
441
        }
 
442
        return s + "]"
 
443
}
 
444
 
 
445
func (n arrayNode) Sigs() sigSet {
 
446
        return n.set
 
447
}
 
448
 
 
449
func (n arrayNode) Value(sig Signature) (interface{}, error) {
 
450
        if n.set.Empty() {
 
451
                // no type information whatsoever, so this must be an empty slice
 
452
                return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
 
453
        }
 
454
        if !n.set[sig] {
 
455
                return nil, varTypeError{n.String(), sig}
 
456
        }
 
457
        s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
 
458
        for i, v := range n.children {
 
459
                rv, err := v.Value(Signature{sig.str[1:]})
 
460
                if err != nil {
 
461
                        return nil, err
 
462
                }
 
463
                s.Index(i).Set(reflect.ValueOf(rv))
 
464
        }
 
465
        return s.Interface(), nil
 
466
}
 
467
 
 
468
func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
 
469
        var n arrayNode
 
470
        if sig.str != "" {
 
471
                n.set = sigSet{sig: true}
 
472
        }
 
473
        if t := p.next(); t.typ == tokArrayEnd {
 
474
                return n, nil
 
475
        } else {
 
476
                p.backup()
 
477
        }
 
478
Loop:
 
479
        for {
 
480
                t := p.next()
 
481
                switch t.typ {
 
482
                case tokEOF:
 
483
                        return nil, io.ErrUnexpectedEOF
 
484
                case tokError:
 
485
                        return nil, errors.New(t.val)
 
486
                }
 
487
                p.backup()
 
488
                cn, err := varMakeNode(p)
 
489
                if err != nil {
 
490
                        return nil, err
 
491
                }
 
492
                if cset := cn.Sigs(); !cset.Empty() {
 
493
                        if n.set.Empty() {
 
494
                                n.set = cset.ToArray()
 
495
                        } else {
 
496
                                nset := cset.ToArray().Intersect(n.set)
 
497
                                if nset.Empty() {
 
498
                                        return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
 
499
                                }
 
500
                                n.set = nset
 
501
                        }
 
502
                }
 
503
                n.children = append(n.children, cn)
 
504
                switch t := p.next(); t.typ {
 
505
                case tokEOF:
 
506
                        return nil, io.ErrUnexpectedEOF
 
507
                case tokError:
 
508
                        return nil, errors.New(t.val)
 
509
                case tokArrayEnd:
 
510
                        break Loop
 
511
                case tokComma:
 
512
                        continue
 
513
                default:
 
514
                        return nil, fmt.Errorf("unexpected %q", t.val)
 
515
                }
 
516
        }
 
517
        return n, nil
 
518
}
 
519
 
 
520
type variantNode struct {
 
521
        n varNode
 
522
}
 
523
 
 
524
var variantSet = sigSet{
 
525
        Signature{"v"}: true,
 
526
}
 
527
 
 
528
func (variantNode) Infer() (Signature, error) {
 
529
        return Signature{"v"}, nil
 
530
}
 
531
 
 
532
func (n variantNode) String() string {
 
533
        return "<" + n.n.String() + ">"
 
534
}
 
535
 
 
536
func (variantNode) Sigs() sigSet {
 
537
        return variantSet
 
538
}
 
539
 
 
540
func (n variantNode) Value(sig Signature) (interface{}, error) {
 
541
        if sig.str != "v" {
 
542
                return nil, varTypeError{n.String(), sig}
 
543
        }
 
544
        sig, err := varInfer(n.n)
 
545
        if err != nil {
 
546
                return nil, err
 
547
        }
 
548
        v, err := n.n.Value(sig)
 
549
        if err != nil {
 
550
                return nil, err
 
551
        }
 
552
        return MakeVariant(v), nil
 
553
}
 
554
 
 
555
func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
 
556
        n, err := varMakeNode(p)
 
557
        if err != nil {
 
558
                return nil, err
 
559
        }
 
560
        if t := p.next(); t.typ != tokVariantEnd {
 
561
                return nil, fmt.Errorf("unexpected %q", t.val)
 
562
        }
 
563
        vn := variantNode{n}
 
564
        if sig.str != "" && sig.str != "v" {
 
565
                return nil, varTypeError{vn.String(), sig}
 
566
        }
 
567
        return variantNode{n}, nil
 
568
}
 
569
 
 
570
type dictEntry struct {
 
571
        key, val varNode
 
572
}
 
573
 
 
574
type dictNode struct {
 
575
        kset, vset sigSet
 
576
        children   []dictEntry
 
577
        val        interface{}
 
578
}
 
579
 
 
580
func (n dictNode) Infer() (Signature, error) {
 
581
        for _, v := range n.children {
 
582
                ksig, err := varInfer(v.key)
 
583
                if err != nil {
 
584
                        continue
 
585
                }
 
586
                vsig, err := varInfer(v.val)
 
587
                if err != nil {
 
588
                        continue
 
589
                }
 
590
                return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
 
591
        }
 
592
        return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
 
593
}
 
594
 
 
595
func (n dictNode) String() string {
 
596
        s := "{"
 
597
        for i, v := range n.children {
 
598
                s += v.key.String() + ": " + v.val.String()
 
599
                if i != len(n.children)-1 {
 
600
                        s += ", "
 
601
                }
 
602
        }
 
603
        return s + "}"
 
604
}
 
605
 
 
606
func (n dictNode) Sigs() sigSet {
 
607
        r := sigSet{}
 
608
        for k := range n.kset {
 
609
                for v := range n.vset {
 
610
                        sig := "a{" + k.str + v.str + "}"
 
611
                        r[Signature{sig}] = true
 
612
                }
 
613
        }
 
614
        return r
 
615
}
 
616
 
 
617
func (n dictNode) Value(sig Signature) (interface{}, error) {
 
618
        set := n.Sigs()
 
619
        if set.Empty() {
 
620
                // no type information -> empty dict
 
621
                return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
 
622
        }
 
623
        if !set[sig] {
 
624
                return nil, varTypeError{n.String(), sig}
 
625
        }
 
626
        m := reflect.MakeMap(typeFor(sig.str))
 
627
        ksig := Signature{sig.str[2:3]}
 
628
        vsig := Signature{sig.str[3 : len(sig.str)-1]}
 
629
        for _, v := range n.children {
 
630
                kv, err := v.key.Value(ksig)
 
631
                if err != nil {
 
632
                        return nil, err
 
633
                }
 
634
                vv, err := v.val.Value(vsig)
 
635
                if err != nil {
 
636
                        return nil, err
 
637
                }
 
638
                m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
 
639
        }
 
640
        return m.Interface(), nil
 
641
}
 
642
 
 
643
func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
 
644
        var n dictNode
 
645
 
 
646
        if sig.str != "" {
 
647
                if len(sig.str) < 5 {
 
648
                        return nil, fmt.Errorf("invalid signature %q for dict type", sig)
 
649
                }
 
650
                ksig := Signature{string(sig.str[2])}
 
651
                vsig := Signature{sig.str[3 : len(sig.str)-1]}
 
652
                n.kset = sigSet{ksig: true}
 
653
                n.vset = sigSet{vsig: true}
 
654
        }
 
655
        if t := p.next(); t.typ == tokDictEnd {
 
656
                return n, nil
 
657
        } else {
 
658
                p.backup()
 
659
        }
 
660
Loop:
 
661
        for {
 
662
                t := p.next()
 
663
                switch t.typ {
 
664
                case tokEOF:
 
665
                        return nil, io.ErrUnexpectedEOF
 
666
                case tokError:
 
667
                        return nil, errors.New(t.val)
 
668
                }
 
669
                p.backup()
 
670
                kn, err := varMakeNode(p)
 
671
                if err != nil {
 
672
                        return nil, err
 
673
                }
 
674
                if kset := kn.Sigs(); !kset.Empty() {
 
675
                        if n.kset.Empty() {
 
676
                                n.kset = kset
 
677
                        } else {
 
678
                                n.kset = kset.Intersect(n.kset)
 
679
                                if n.kset.Empty() {
 
680
                                        return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
 
681
                                }
 
682
                        }
 
683
                }
 
684
                t = p.next()
 
685
                switch t.typ {
 
686
                case tokEOF:
 
687
                        return nil, io.ErrUnexpectedEOF
 
688
                case tokError:
 
689
                        return nil, errors.New(t.val)
 
690
                case tokColon:
 
691
                default:
 
692
                        return nil, fmt.Errorf("unexpected %q", t.val)
 
693
                }
 
694
                t = p.next()
 
695
                switch t.typ {
 
696
                case tokEOF:
 
697
                        return nil, io.ErrUnexpectedEOF
 
698
                case tokError:
 
699
                        return nil, errors.New(t.val)
 
700
                }
 
701
                p.backup()
 
702
                vn, err := varMakeNode(p)
 
703
                if err != nil {
 
704
                        return nil, err
 
705
                }
 
706
                if vset := vn.Sigs(); !vset.Empty() {
 
707
                        if n.vset.Empty() {
 
708
                                n.vset = vset
 
709
                        } else {
 
710
                                n.vset = n.vset.Intersect(vset)
 
711
                                if n.vset.Empty() {
 
712
                                        return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
 
713
                                }
 
714
                        }
 
715
                }
 
716
                n.children = append(n.children, dictEntry{kn, vn})
 
717
                t = p.next()
 
718
                switch t.typ {
 
719
                case tokEOF:
 
720
                        return nil, io.ErrUnexpectedEOF
 
721
                case tokError:
 
722
                        return nil, errors.New(t.val)
 
723
                case tokDictEnd:
 
724
                        break Loop
 
725
                case tokComma:
 
726
                        continue
 
727
                default:
 
728
                        return nil, fmt.Errorf("unexpected %q", t.val)
 
729
                }
 
730
        }
 
731
        return n, nil
 
732
}
 
733
 
 
734
type byteStringNode []byte
 
735
 
 
736
var byteStringSet = sigSet{
 
737
        Signature{"ay"}: true,
 
738
}
 
739
 
 
740
func (byteStringNode) Infer() (Signature, error) {
 
741
        return Signature{"ay"}, nil
 
742
}
 
743
 
 
744
func (b byteStringNode) String() string {
 
745
        return string(b)
 
746
}
 
747
 
 
748
func (b byteStringNode) Sigs() sigSet {
 
749
        return byteStringSet
 
750
}
 
751
 
 
752
func (b byteStringNode) Value(sig Signature) (interface{}, error) {
 
753
        if sig.str != "ay" {
 
754
                return nil, varTypeError{b.String(), sig}
 
755
        }
 
756
        return []byte(b), nil
 
757
}
 
758
 
 
759
func varParseByteString(s string) ([]byte, error) {
 
760
        // quotes and b at start are guaranteed to be there
 
761
        b := make([]byte, 0, 1)
 
762
        s = s[2 : len(s)-1]
 
763
        for len(s) != 0 {
 
764
                c := s[0]
 
765
                s = s[1:]
 
766
                if c != '\\' {
 
767
                        b = append(b, c)
 
768
                        continue
 
769
                }
 
770
                c = s[0]
 
771
                s = s[1:]
 
772
                switch c {
 
773
                case 'a':
 
774
                        b = append(b, 0x7)
 
775
                case 'b':
 
776
                        b = append(b, 0x8)
 
777
                case 'f':
 
778
                        b = append(b, 0xc)
 
779
                case 'n':
 
780
                        b = append(b, '\n')
 
781
                case 'r':
 
782
                        b = append(b, '\r')
 
783
                case 't':
 
784
                        b = append(b, '\t')
 
785
                case 'x':
 
786
                        if len(s) < 2 {
 
787
                                return nil, errors.New("short escape")
 
788
                        }
 
789
                        n, err := strconv.ParseUint(s[:2], 16, 8)
 
790
                        if err != nil {
 
791
                                return nil, err
 
792
                        }
 
793
                        b = append(b, byte(n))
 
794
                        s = s[2:]
 
795
                case '0':
 
796
                        if len(s) < 3 {
 
797
                                return nil, errors.New("short escape")
 
798
                        }
 
799
                        n, err := strconv.ParseUint(s[:3], 8, 8)
 
800
                        if err != nil {
 
801
                                return nil, err
 
802
                        }
 
803
                        b = append(b, byte(n))
 
804
                        s = s[3:]
 
805
                default:
 
806
                        b = append(b, c)
 
807
                }
 
808
        }
 
809
        return append(b, 0), nil
 
810
}
 
811
 
 
812
func varInfer(n varNode) (Signature, error) {
 
813
        if sig, ok := n.Sigs().Single(); ok {
 
814
                return sig, nil
 
815
        }
 
816
        return n.Infer()
 
817
}