URIエンコーディング / percent encoding

ネットワーク実験に必要なので、URIエンコード/デコードを実装。ググってもなかなか既存のライブラリがでてこなかった。

URI::encode("べっ、別にあんたのために実装したんじゃないんだからねっ");
=>  "%e3%81%b9%e3%81%a3%e3%80%81%e5%88%a5%e3%81%ab%e3%81%82%e3%82%93%e3%81%9f%e3%81%ae%e3%81%9f%e3%82%81%e3%81%ab%e5%ae%9f%e8%a3%85%e3%81%97%e3%81%9f%e3%82%93%e3%81%98%e3%82%83%e3%81%aa%e3%81%84%e3%82%93%e3%81%a0%e3%81%8b%e3%82%89%e3%81%ad%e3%81%a3"

URI::decode("%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BB%E3%81%97%E3%81%8F%E3%81%AA%E3%82%93%E3%81%A6%E3%81%AA%E3%81%84%E3%82%93%E3%81%A0%E3%81%8B%E3%82%89%E3%81%A3") ;
=> "使ってほしくなんてないんだからっ"
class URI {
private:

public:
    static bool reserved_char(char c){
        if (('a' <= c & c <= 'z')
            | ('A' <= c & c <= 'Z')
            | c == '-'
            | c == '_'
            | c == '.'
            | c == '~'
            | c == ' ')
            return false;
        else
            return true;
    }

    static string encode(const char* c_str){
        string str(c_str);
        return URI::encode(str);
    }

    static string encode(string& str){
        ostringstream ret;

        for(u_int i = 0;i < str.length();i++){
            if (str[i] == ' '){
                ret << '+';
            }else if (URI::reserved_char(str[i])){
                unsigned char c = str[i];
                ret << '%';
                ret.setf(ios::hex, ios::basefield);
                ret << (u_int)c;
                ret.unsetf(ios::hex);
            } else{
                ret << str[i];
            }
        }

        return ret.str();
    }

    static string decode(const char* c_str){
        string str(c_str);
        return URI::decode(str);
    }

    static string decode(string& str){
        ostringstream ret;

        for(u_int i = 0;i < str.length();i++){
            if (str[i] == '%'){
                unsigned char c;
                char *endptr;
                c = (unsigned char)strtol(str.substr(i+1, 2).c_str()
                                          ,&endptr
                                          ,16);
                ret << c;
                i += 2;
            }else{
                ret << str[i];
            }
        }

        return ret.str();
    }

};