(s string, quote rune)
| 662 | var errBadUTF8 = errors.New("proto: bad UTF-8") |
| 663 | |
| 664 | func unquoteC(s string, quote rune) (string, error) { |
| 665 | // This is based on C++'s tokenizer.cc. |
| 666 | // Despite its name, this is *not* parsing C syntax. |
| 667 | // For instance, "\0" is an invalid quoted string. |
| 668 | |
| 669 | // Avoid allocation in trivial cases. |
| 670 | simple := true |
| 671 | for _, r := range s { |
| 672 | if r == '\\' || r == quote { |
| 673 | simple = false |
| 674 | break |
| 675 | } |
| 676 | } |
| 677 | if simple { |
| 678 | return s, nil |
| 679 | } |
| 680 | |
| 681 | buf := make([]byte, 0, 3*len(s)/2) |
| 682 | for len(s) > 0 { |
| 683 | r, n := utf8.DecodeRuneInString(s) |
| 684 | if r == utf8.RuneError && n == 1 { |
| 685 | return "", errBadUTF8 |
| 686 | } |
| 687 | s = s[n:] |
| 688 | if r != '\\' { |
| 689 | if r < utf8.RuneSelf { |
| 690 | buf = append(buf, byte(r)) |
| 691 | } else { |
| 692 | buf = append(buf, string(r)...) |
| 693 | } |
| 694 | continue |
| 695 | } |
| 696 | |
| 697 | ch, tail, err := unescape(s) |
| 698 | if err != nil { |
| 699 | return "", err |
| 700 | } |
| 701 | buf = append(buf, ch...) |
| 702 | s = tail |
| 703 | } |
| 704 | return string(buf), nil |
| 705 | } |
| 706 | |
| 707 | func unescape(s string) (ch string, tail string, err error) { |
| 708 | r, n := utf8.DecodeRuneInString(s) |
no test coverage detected