/// <summary> /// Decodes a string using URI encoding. /// </summary> /// <param name="value">The string to decode.</param> /// <returns>The decoded string.</returns> public static string UriDecode(string value) { if (value == null) { throw new ArgumentNullException("value"); } var sb = new StringBuilder(); for (int i = 0; i < value.Length; i++) { if ( value[i] == '%' && i < value.Length - 2 && CharEx.IsHex(value[i + 1]) && CharEx.IsHex(value[i + 2]) ) { sb.Append( (char)(CharEx.HexToInt(value[i + 1]) * 16 + CharEx.HexToInt(value[i + 2])) ); i += 2; } else if (value[i] == '+') { sb.Append(' '); } else { sb.Append(value[i]); } } return(sb.ToString()); }
/// <summary> /// Decodes a string using HTML encoding. /// </summary> /// <param name="value">The string to be decoded.</param> /// <returns>The decode string.</returns> public static string HtmlDecode(string value) { if (value == null) { throw new ArgumentNullException("value"); } var sb = new StringBuilder(); for (int i = 0; i < value.Length; i++) { if (value[i] == '&' && value.Length > i + 2) { // Scan for the ;. int maxSearch = Math.Min(value.Length, i + _longestHtmlEntity + 2); int endPosition = -1; for (int j = i + 1; j < maxSearch; j++) { if (value[j] == ';') { endPosition = j; break; } } // If we did not find an end separator, just skip over this // entity and treat is at text. if (endPosition == -1) { sb.Append(value[i]); continue; } // Are we in a numeric separator? if (value[i + 1] == '#') { int offset = 2; bool isHexNumeric = false; if (value[i + 2] == 'x' || value[i + 2] == 'X') { isHexNumeric = true; offset++; } // All parts of the numeric separator must be digits. bool isNumeric = true; for (int j = i + offset; j < endPosition; j++) { if (!( Char.IsDigit(value[j]) || (isHexNumeric && CharEx.IsHex(value[j])) )) { isNumeric = false; break; } } // If not all numeric, just skip over this // entity and treat is at text. if (!isNumeric) { sb.Append(value[i]); continue; } // Convert the numeric entity to unicode. string numericEntity = value.Substring(i + offset, endPosition - (i + offset)); sb.Append((char)int.Parse(numericEntity, isHexNumeric ? NumberStyles.HexNumber : NumberStyles.Integer)); i = endPosition; } else { string entity = value.Substring(i + 1, endPosition - (i + 1)); int codePoint; if (_htmlEntities.TryGetValueByItem1(entity, out codePoint)) { sb.Append((char)codePoint); i = endPosition; } else { // If we don't know the entity, just skip over this // entity and treat is at text. sb.Append(value[i]); } } } else { sb.Append(value[i]); } } return(sb.ToString()); }
public static string StringDecode(string value) { if (String.IsNullOrEmpty(value)) { return(value); } var state = StringDecodeState.None; var sb = new StringBuilder(); var escapeCache = new StringBuilder(); int i = 0; while (i <= value.Length) { char c; bool atEnd = i == value.Length; if (i < value.Length) { c = value[i]; } else { c = '\0'; } switch (state) { case StringDecodeState.None: if (!atEnd) { if (c == '\\') { state = StringDecodeState.Escape; } else { sb.Append(c); } } break; case StringDecodeState.Escape: if (atEnd) { sb.Append('\\'); } else { switch (Char.ToLowerInvariant(c)) { case 'a': sb.Append('\a'); break; case 'b': sb.Append('\b'); break; case 't': sb.Append('\t'); break; case 'r': sb.Append('\r'); break; case 'v': sb.Append('\v'); break; case 'f': sb.Append('\f'); break; case 'n': sb.Append('\n'); break; case 'e': sb.Append('\u001B'); break; case '\'': sb.Append('\''); break; case '"': sb.Append('"'); break; case '\\': sb.Append('\\'); break; case 'u': state = StringDecodeState.UnicodeEscape; break; case 'x': state = StringDecodeState.HexEscape; break; default: if (CharEx.IsOct(c)) { i--; state = StringDecodeState.OctEscape; } else { sb.Append(c); } break; } if (state == StringDecodeState.Escape) { state = StringDecodeState.None; } } break; case StringDecodeState.OctEscape: if ( !atEnd && CharEx.IsOct(c) && escapeCache.Length < 3 ) { escapeCache.Append(c); } else { if (escapeCache.Length > 0) { sb.Append(CharEx.FromOct(escapeCache.ToString())); } if (!atEnd) { state = StringDecodeState.None; escapeCache = new StringBuilder(); i--; } } break; case StringDecodeState.HexEscape: case StringDecodeState.UnicodeEscape: if ( !atEnd && CharEx.IsHex(c) && escapeCache.Length < (state == StringDecodeState.HexEscape ? 2 : 4) ) { escapeCache.Append(c); } else { if (escapeCache.Length == 0) { sb.Append(state == StringDecodeState.HexEscape ? 'x' : 'u'); } else { sb.Append(CharEx.FromHex(escapeCache.ToString())); } if (!atEnd) { state = StringDecodeState.None; escapeCache = new StringBuilder(); i--; } } break; default: Debug.Fail("Illegal state"); return(null); } i++; } return(sb.ToString()); }