/// <summary>
        /// Unquote a string.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string Unquote(string s)
        {
            if (s == null)
            {
                return(null);
            }
            if (s.Length < 2)
            {
                return(s);
            }

            char first = s[0];
            char last  = s[s.Length - 1];

            if (first != last || (first != '"' && first != '\''))
            {
                return(s);
            }

            StringBuilder b = new StringBuilder(s.Length - 2);

            lock (b)
            {
                bool escape = false;
                for (int i = 1; i < s.Length - 1; i++)
                {
                    char c = s[i];

                    if (escape)
                    {
                        escape = false;
                        switch (c)
                        {
                        case 'n':
                            b.Append('\n');
                            break;

                        case 'r':
                            b.Append('\r');
                            break;

                        case 't':
                            b.Append('\t');
                            break;

                        case 'f':
                            b.Append('\f');
                            break;

                        case 'b':
                            b.Append('\b');
                            break;

                        case 'u':
                            b.Append((char)(
                                         (TypeUtil.ConvertHexDigit((byte)s[i++]) << 24) +
                                         (TypeUtil.ConvertHexDigit((byte)s[i++]) << 16) +
                                         (TypeUtil.ConvertHexDigit((byte)s[i++]) << 8) +
                                         (TypeUtil.ConvertHexDigit((byte)s[i++]))
                                         )
                                     );
                            break;

                        default:
                            b.Append(c);
                            break;
                        }
                    }
                    else if (c == '\\')
                    {
                        escape = true;
                        continue;
                    }
                    else
                    {
                        b.Append(c);
                    }
                }

                return(b.ToString());
            }
        }
示例#2
0
        /// <summary>
        /// Decode string with % encoding.
        /// This method makes the assumption that the majority of calls
        /// will need no decoding.
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <param name="charset"></param>
        /// <returns></returns>
        public static string DecodeString(string encoded, int offset, int length, string charset)
        {
            if (charset == null || StringUtil.IsUTF8(charset))
            {
                Utf8StringBuffer buffer = null;

                for (int i = 0; i < length; i++)
                {
                    char c = encoded[offset + i];
                    if (c < 0 || c > 0xff)
                    {
                        if (buffer == null)
                        {
                            buffer = new Utf8StringBuffer(length);
                            buffer.Append(encoded, offset, i + 1);
                        }
                        else
                        {
                            buffer.Append((byte)c);
                        }
                    }
                    else if (c == '+')
                    {
                        if (buffer == null)
                        {
                            buffer = new Utf8StringBuffer(length);
                            buffer.Append(encoded, offset, i);
                        }

                        buffer.Append((byte)' ');
                    }
                    else if (c == '%' && (i + 2) < length)
                    {
                        if (buffer == null)
                        {
                            buffer = new Utf8StringBuffer(length);
                            buffer.Append(encoded, offset, i);
                        }

                        while (c == '%' && (i + 2) < length)
                        {
                            try
                            {
                                byte b = (byte)TypeUtil.ParseInt(encoded, offset + i + 1, 2, 16);
                                buffer.Append(b);
                                i += 3;
                            }
                            catch (FormatException)
                            {
                                buffer.Append('%');
                                for (char next; ((next = encoded[++i + offset]) != '%');)
                                {
                                    buffer.Append((next == '+' ? ' ' : next));
                                }
                            }

                            if (i < length)
                            {
                                c = encoded[offset + i];
                            }
                        }
                        i--;
                    }
                    else if (buffer != null)
                    {
                        buffer.Append((byte)c);
                    }
                }

                if (buffer == null)
                {
                    if (offset == 0 && encoded.Length == length)
                    {
                        return(encoded);
                    }
                    return(encoded.Substring(offset, length));
                }

                return(buffer.ToString());
            }
            else
            {
                StringBuilder buffer = null;

                try
                {
                    for (int i = 0; i < length; i++)
                    {
                        char c = encoded[offset + i];
                        if (c < 0 || c > 0xff)
                        {
                            if (buffer == null)
                            {
                                buffer = new StringBuilder(length);
                                buffer.Append(encoded, offset, i + 1);
                            }
                            else
                            {
                                buffer.Append(c);
                            }
                        }
                        else if (c == '+')
                        {
                            if (buffer == null)
                            {
                                buffer = new StringBuilder(length);
                                buffer.Append(encoded, offset, i);
                            }

                            buffer.Append(' ');
                        }
                        else if (c == '%' && (i + 2) < length)
                        {
                            if (buffer == null)
                            {
                                buffer = new StringBuilder(length);
                                buffer.Append(encoded, offset, i);
                            }

                            byte[] ba = new byte[length];
                            int    n  = 0;
                            while (c >= 0 && c <= 0xff)
                            {
                                if (c == '%')
                                {
                                    if (i + 2 < length)
                                    {
                                        try
                                        {
                                            ba[n++] = (byte)TypeUtil.ParseInt(encoded, offset + i + 1, 2, 16);
                                            i      += 3;
                                        }
                                        catch (FormatException)
                                        {
                                            ba[n - 1] = (byte)'%';
                                            for (char next; ((next = encoded[++i + offset]) != '%');)
                                            {
                                                ba[n++] = (byte)(next == '+' ? ' ' : next);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        ba[n++] = (byte)'%';
                                        i++;
                                    }
                                }
                                else if (c == '+')
                                {
                                    ba[n++] = (byte)' ';
                                    i++;
                                }
                                else
                                {
                                    ba[n++] = (byte)c;
                                    i++;
                                }

                                if (i >= length)
                                {
                                    break;
                                }
                                c = encoded[offset + i];
                            }

                            i--;
                            string str = Encoding.GetEncoding(charset).GetString(ba, 0, n);
                            buffer.Append(str);
                        }
                        else if (buffer != null)
                        {
                            buffer.Append(c);
                        }
                    }

                    if (buffer == null)
                    {
                        if (offset == 0 && encoded.Length == length)
                        {
                            return(encoded);
                        }
                        return(encoded.Substring(offset, length));
                    }

                    return(buffer.ToString());
                }
                catch (ArgumentException e)
                {
                    throw new SystemException(e.Message, e);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Decoded parameters to Map.
        /// </summary>
        /// <param name="input">InputSteam to read</param>
        /// <param name="map">MultiMap to Add parameters to</param>
        /// <param name="maxLength">maximum length of conent to read 0r -1 for no limit</param>
        public static void DecodeUtf8To(Stream input, MultiMap <string> map, int maxLength)
        {
            lock (map)
            {
                Utf8StringBuilder buffer = new Utf8StringBuilder();
                string            key    = null;
                string            value  = null;

                int b;

                // TODO cache of parameter names ???
                int totalLength = 0;
                while ((b = input.ReadByte()) >= 0)
                {
                    switch ((char)b)
                    {
                    case '&':
                        value = buffer.Length == 0 ? "" : buffer.ToString();
                        buffer.Reset();
                        if (key != null)
                        {
                            map.Append(key, value);
                        }
                        else if (value != null && value.Length > 0)
                        {
                            map.Append(value, "");
                        }
                        key   = null;
                        value = null;
                        break;

                    case '=':
                        if (key != null)
                        {
                            buffer.Append((byte)b);
                            break;
                        }
                        key = buffer.ToString();
                        buffer.Reset();
                        break;

                    case '+':
                        buffer.Append((byte)' ');
                        break;

                    case '%':
                        int dh = input.ReadByte();
                        int dl = input.ReadByte();
                        if (dh < 0 || dl < 0)
                        {
                            break;
                        }
                        buffer.Append((byte)((TypeUtil.ConvertHexDigit((byte)dh) << 4) + TypeUtil.ConvertHexDigit((byte)dl)));
                        break;

                    default:
                        buffer.Append((byte)b);
                        break;
                    }
                    if (maxLength >= 0 && (++totalLength > maxLength))
                    {
                        throw new InvalidOperationException("Form too large");
                    }
                }

                if (key != null)
                {
                    value = buffer.Length == 0 ? "" : buffer.ToString();
                    buffer.Reset();
                    map.Append(key, value);
                }
                else if (buffer.Length > 0)
                {
                    map.Append(buffer.ToString(), "");
                }
            }
        }
示例#4
0
        /// <summary>
        /// Decoded parameters to Map.
        /// </summary>
        /// <param name="input">the stream containing the encoded parameters</param>
        /// <param name="map"></param>
        /// <param name="charset"></param>
        /// <param name="maxLength"></param>
        public static void DecodeTo(Stream input, MultiMap <string> map, string charset, int maxLength)
        {
            if (charset == null || StringUtil.__ISO_8859_1.Equals(charset))
            {
                Decode88591To(input, map, maxLength);
                return;
            }

            if (StringUtil.__UTF8.Equals(charset, StringComparison.OrdinalIgnoreCase))
            {
                DecodeUtf8To(input, map, maxLength);
                return;
            }

            if (StringUtil.__UTF16.Equals(charset, StringComparison.OrdinalIgnoreCase)) // Should be all 2 byte encodings
            {
                DecodeUtf16To(input, map, maxLength);
                return;
            }


            lock (map)
            {
                string key   = null;
                string value = null;

                int c;
                int digit  = 0;
                int digits = 0;

                int totalLength = 0;
                ByteArrayOutputStream2 output = new ByteArrayOutputStream2();
                input.Position = 0;
                long size = 0;

                while ((c = input.ReadByte()) > 0)
                {
                    switch ((char)c)
                    {
                    case '&':
                        size            = output.Length;
                        value           = size == 0 ? "" : Encoding.GetEncoding(charset).GetString(output.GetBuffer(), 0, (int)size);
                        output.Position = 0;
                        if (key != null)
                        {
                            map.Append(key, value);
                        }
                        else if (value != null && value.Length > 0)
                        {
                            map.Append(value, "");
                        }
                        key   = null;
                        value = null;
                        break;

                    case '=':
                        if (key != null)
                        {
                            output.WriteByte(c);
                            break;
                        }
                        size            = output.Length;
                        key             = size == 0 ? "" : Encoding.GetEncoding(charset).GetString(output.GetBuffer(), 0, (int)size);
                        output.Position = 0;
                        break;

                    case '+':
                        output.WriteByte(' ');
                        break;

                    case '%':
                        digits = 2;
                        break;

                    default:
                        if (digits == 2)
                        {
                            digit  = TypeUtil.ConvertHexDigit((byte)c);
                            digits = 1;
                        }
                        else if (digits == 1)
                        {
                            int v = (byte)(digit << 4) + TypeUtil.ConvertHexDigit((byte)c);
                            output.WriteByte(v);
                            digits = 0;
                        }
                        else
                        {
                            output.WriteByte((byte)c);
                        }
                        break;
                    }

                    totalLength++;
                    if (maxLength >= 0 && totalLength > maxLength)
                    {
                        throw new InvalidOperationException("Form too large");
                    }
                }

                size = output.Length;
                if (key != null)
                {
                    value           = size == 0 ? "" : Encoding.GetEncoding(charset).GetString(output.GetBuffer(), 0, (int)size);
                    output.Position = 0;
                    map.Append(key, value);
                }
                else if (size > 0)
                {
                    map.Append(Encoding.GetEncoding(charset).GetString(output.GetBuffer(), 0, (int)size), "");
                }
            }
        }
示例#5
0
        /* -------------------------------------------------------------- */

        /** Decoded parameters to Map.
         * @param data the byte[] containing the encoded parameters
         */
        public static void DecodeUtf8To(byte[] raw, int offset, int length, MultiMap <string> map, Utf8StringBuilder buffer)
        {
            lock (map)
            {
                string key   = null;
                string value = null;

                // TODO cache of parameter names ???
                int end = offset + length;
                for (int i = offset; i < end; i++)
                {
                    byte b = raw[i];
                    switch ((char)(0xff & b))
                    {
                    case '&':
                        value = buffer.Length == 0 ? "" : buffer.ToString();
                        buffer.Reset();
                        if (key != null)
                        {
                            map.Append(key, value);
                        }
                        else if (value != null && value.Length > 0)
                        {
                            map.Append(value, "");
                        }
                        key   = null;
                        value = null;
                        break;

                    case '=':
                        if (key != null)
                        {
                            buffer.Append(b);
                            break;
                        }
                        key = buffer.ToString();
                        buffer.Reset();
                        break;

                    case '+':
                        buffer.Append((byte)' ');
                        break;

                    case '%':
                        if (i + 2 < end)
                        {
                            buffer.Append((byte)((TypeUtil.ConvertHexDigit(raw[++i]) << 4) + TypeUtil.ConvertHexDigit(raw[++i])));
                        }
                        break;

                    default:
                        buffer.Append(b);
                        break;
                    }
                }

                if (key != null)
                {
                    value = buffer.Length == 0 ? "" : buffer.ToString();
                    buffer.Reset();
                    map.Append(key, value);
                }
                else if (buffer.Length > 0)
                {
                    map.Append(buffer.ToString(), "");
                }
            }
        }