Contains utility methods to work with characters.
예제 #1
0
        /// <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());
        }
예제 #2
0
        /// <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());
        }
예제 #3
0
        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());
        }