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
264 val interface{}
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
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
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
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
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 }
818
View as plain text