コード例 #1
0
        static string DecodeComponent(string s, int from, int toExcluded, Encoding charset, bool isPath)
        {
            int len = toExcluded - from;

            if (len <= 0)
            {
                return(StringUtil.EmptyString);
            }
            int firstEscaped = -1;

            for (int i = from; i < toExcluded; i++)
            {
                char c = s[i];
                if (c == HttpConstants.PercentChar || c == HttpConstants.PlusSignChar && !isPath)
                {
                    firstEscaped = i;
                    break;
                }
            }
            if (firstEscaped == -1)
            {
                return(s.Substring(from, len));
            }

            // Each encoded byte takes 3 characters (e.g. "%20")
            int decodedCapacity = (toExcluded - firstEscaped) / 3;
            var byteBuf         = new byte[decodedCapacity];
            int idx;
            var strBuf = StringBuilderManager.Allocate(len);

            _ = strBuf.Append(s, from, firstEscaped - from);

            for (int i = firstEscaped; i < toExcluded; i++)
            {
                char c = s[i];
                if (c != HttpConstants.PercentChar)
                {
                    _ = strBuf.Append(c != HttpConstants.PlusSignChar || isPath ? c : StringUtil.Space);
                    continue;
                }

                idx = 0;
                do
                {
                    if (i + 3 > toExcluded)
                    {
                        StringBuilderManager.Free(strBuf); ThrowHelper.ThrowArgumentException_UnterminatedEscapeSeq(i, s);
                    }
                    byteBuf[idx++] = StringUtil.DecodeHexByte(s, i + 1);
                    i += 3;
                }while (i < toExcluded && s[i] == HttpConstants.PercentChar);
                i--;

                _ = strBuf.Append(charset.GetString(byteBuf, 0, idx));
            }

            return(StringBuilderManager.ReturnAndFree(strBuf));
        }