variant_parser.go (15692B)
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 }