public static string Unescape(string s)
{
s = s.Replace('+', ' ');
var result = new StringBuilder();
var p = 0;
int pp;
while ( ( pp = s.IndexOf('%', p) ) >= 0 ) {
result.Append(s.Substring(p, pp - p));
p = pp;
var c0 = ( HexToInt(s[p + 1]) << 4 ) + HexToInt(s[p + 2]);
if ( c0 < 0x80 ) {
p += 3;
result.Append((char)c0);
continue;
}
var c1 = ( HexToInt(s[p + 4]) << 4 ) + HexToInt(s[p + 5]);
if ( c0 < 0xe0 ) {
p += 6;
var c = (char)( ( ( c0 & 0x1f ) << 6 ) + ( c1 & 0x7f ) );
result.Append(c);
continue;
}
var c2 = ( HexToInt(s[p + 7]) << 4 ) + HexToInt(s[p + 8]);
if ( c0 < 0xf1 ) {
p += 9;
var c = (char)( ( ( c0 & 0x0f ) << 12 ) + ( ( c1 & 0x7f ) << 6 ) + ( c2 & 0x7f ) );
result.Append(c);
continue;
}
throw new FormatException("Charcorde over 0xffff is not supported");
}
return result.Append(s.Substring(p)).ToString();
}