| 775 | |
| 776 | |
| 777 | string encode(const string& s, const string& additional_chars) |
| 778 | { |
| 779 | ostringstream out; |
| 780 | |
| 781 | foreach (unsigned char c, s) { |
| 782 | switch (c) { |
| 783 | // Reserved characters. |
| 784 | case '$': |
| 785 | case '&': |
| 786 | case '+': |
| 787 | case ',': |
| 788 | case '/': |
| 789 | case ':': |
| 790 | case ';': |
| 791 | case '=': |
| 792 | case '?': |
| 793 | case '@': |
| 794 | // Unsafe characters. |
| 795 | case ' ': |
| 796 | case '"': |
| 797 | case '<': |
| 798 | case '>': |
| 799 | case '#': |
| 800 | case '%': |
| 801 | case '{': |
| 802 | case '}': |
| 803 | case '|': |
| 804 | case '\\': |
| 805 | case '^': |
| 806 | case '~': |
| 807 | case '[': |
| 808 | case ']': |
| 809 | case '`': |
| 810 | // NOTE: The cast to unsigned int is needed. |
| 811 | out << '%' << std::setfill('0') << std::setw(2) << std::hex |
| 812 | << std::uppercase << (unsigned int) c; |
| 813 | break; |
| 814 | default: |
| 815 | // ASCII control characters and non-ASCII characters. |
| 816 | // NOTE: The cast to unsigned int is needed. |
| 817 | if (c < 0x20 || |
| 818 | c > 0x7F || |
| 819 | additional_chars.find_first_of(c) != string::npos) { |
| 820 | out << '%' << std::setfill('0') << std::setw(2) << std::hex |
| 821 | << std::uppercase << (unsigned int) c; |
| 822 | } else { |
| 823 | out << c; |
| 824 | } |
| 825 | break; |
| 826 | } |
| 827 | } |
| 828 | |
| 829 | return out.str(); |
| 830 | } |
| 831 | |
| 832 | |
| 833 | Try<string> decode(const string& s) |