private static String Decode(Object encodedURI, URISetType flags){
String encodedURIStr = Convert.ToString(encodedURI);
StringBuilder resultStr = new StringBuilder();
for (int i = 0; i < encodedURIStr.Length; i++){
char ch = encodedURIStr[i];
if (ch != '%')
resultStr.Append(ch);
else{
int start = i;
if (i+2 >= encodedURIStr.Length)
throw new JScriptException(JSError.URIDecodeError);
byte b = HexValue(encodedURIStr[i+1], encodedURIStr[i+2]);
i += 2;
char ch1;
if ((b & 0x80) == 0)
ch1 = (char)b;
else{
int n;
for (n = 1; ((b << n) & 0x80) != 0; n++) ;
if (n == 1 || n > 4 || i + (n-1) * 3 >= encodedURIStr.Length)
throw new JScriptException(JSError.URIDecodeError);
int value = (int)b & 0xFF >> (n+1);
for (; n > 1; n--){
if (encodedURIStr[i+1] != '%')
throw new JScriptException(JSError.URIDecodeError);
b = HexValue(encodedURIStr[i+2], encodedURIStr[i+3]);
i += 3;
// The two leading bits should be 10 for a valid UTF-8 encoding.
if ((b & 0xC0) != 0x80)
throw new JScriptException(JSError.URIDecodeError);
value = value << 6 | (int)(b & 0x3F);
}
if (value >= 0xD800 && value < 0xE000)
throw new JScriptException(JSError.URIDecodeError);
if (value < 0x10000)
ch1 = (char)value;
else{
if (value > 0x10FFFF)
throw new JScriptException(JSError.URIDecodeError);
resultStr.Append((char)((value - 0x10000 >> 10 & 0x3FF) + 0xD800));
resultStr.Append((char)((value - 0x10000 & 0x3FF) + 0xDC00));
continue;
}
}
if (GlobalObject.InURISet(ch1, flags))
resultStr.Append(encodedURIStr, start, i-start+1);
else
resultStr.Append(ch1);
}
}
return resultStr.ToString();
}