示例#1
0
    /// <summary>
    /// Parses a string to the query data.
    /// </summary>
    /// <param name="query">The query string.</param>
    /// <param name="append">true if append instead of override; otherwise, false.</param>
    /// <param name="encoding">The optional encoding.</param>
    /// <returns>The count of query item added.</returns>
    /// <exception cref="FormatException">The format is not correct.</exception>
    public int ParseSet(string query, bool append = false, Encoding encoding = null)
    {
        if (!append)
        {
            Clear();
        }
        if (string.IsNullOrWhiteSpace(query))
        {
            return(0);
        }
        var queryTrim = query.TrimStart();

        if (queryTrim.IndexOf('{') == 0)
        {
            queryTrim = queryTrim.Substring(1).Trim();
            var lastPos = queryTrim.LastIndexOf('}');
            if (lastPos >= 0)
            {
                queryTrim = queryTrim.Substring(0, lastPos);
            }
            var count = 0;

            string        name          = null;
            StringBuilder sb            = null;
            var           level         = new List <char>();
            StringBuilder backSlash     = null;
            bool          ignoreRest    = false;
            bool          lastBackSlash = false;
            foreach (var c in queryTrim)
            {
                if (ignoreRest)
                {
                    switch (c)
                    {
                    case '\r':
                    case '\n':
                        ignoreRest = false;
                        break;
                    }

                    lastBackSlash = false;
                    continue;
                }

                if (c == '\\')
                {
                    if (lastBackSlash)
                    {
                        sb.Append(c);
                    }
                    else
                    {
                        backSlash = new StringBuilder();
                    }

                    lastBackSlash = !lastBackSlash;
                    continue;
                }

                lastBackSlash = false;
                if (backSlash != null)
                {
                    if (StringExtensions.ReplaceBackSlash(sb, backSlash, c))
                    {
                        backSlash = null;
                    }
                    continue;
                }

                if (sb == null)
                {
                    if (c == '/')
                    {
                        ignoreRest = true;
                        continue;
                    }

                    if (c == '"')
                    {
                        sb = new StringBuilder();
                        level.Add('"');
                        continue;
                    }

                    if (name == null)
                    {
                        if (NameChars.IndexOf(c) > -1)
                        {
                            sb = new StringBuilder();
                            level.Add(':');
                            sb.Append(c);
                        }

                        continue;
                    }

                    if (c == '{')
                    {
                        level.Add('}');
                    }
                    else if (c == '[')
                    {
                        level.Add(']');
                    }
                    else if (NumBoolChars.IndexOf(c) > -1)
                    {
                        level.Add(',');
                    }
                    else
                    {
                        continue;
                    }

                    sb = new StringBuilder();
                    sb.Append(c);
                    continue;
                }

                if (level.Count == 0)
                {
                    continue;
                }
                var lastLevelChar = level[level.Count - 1];
                if (c == lastLevelChar)
                {
                    level.RemoveAt(level.Count - 1);
                    if (name == null)
                    {
                        name = sb.ToString();
                        sb   = null;
                        continue;
                    }
                    else if (level.Count == 0)
                    {
                        if (c == ',')
                        {
                            var sbStr = sb.ToString().Trim();
                            sb = new StringBuilder(sbStr);
                            if (sbStr == "null" || sbStr == "undefined")
                            {
                                name = null;
                                sb   = null;
                                continue;
                            }
                        }
                        else if (c == '"')
                        {
                        }
                        else
                        {
                            sb.Append(c);
                        }

                        ListExtensions.Add(this, name, sb.ToString());
                        name = null;
                        sb   = null;
                        continue;
                    }
                }
                else if (lastLevelChar == ':' && name == null)
                {
                    if (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ',' || c == '+')
                    {
                        sb = null;
                    }
                    else if (c == '/')
                    {
                        sb         = null;
                        ignoreRest = true;
                    }
                    else if (NameChars.IndexOf(c) < 0)
                    {
                        throw new FormatException("The format of query string is not correct.");
                    }

                    if (sb == null)
                    {
                        level.RemoveAt(level.Count - 1);
                        continue;
                    }
                }
                else if (c == '"')
                {
                    level.Add('"');
                }
                else if (lastLevelChar != '"')
                {
                    if (c == '{')
                    {
                        level.Add('}');
                    }
                    else if (c == '[')
                    {
                        level.Add(']');
                    }
                }

                if (sb == null)
                {
                    sb = new StringBuilder();
                }
                sb.Append(c);
            }

            if (!string.IsNullOrWhiteSpace(name) && sb != null)
            {
                var sbStr = sb.ToString().Trim();
                if (sbStr != "null" && sbStr != "undefined")
                {
                    ListExtensions.Add(this, name, sbStr);
                }
            }

            return(count);
        }

        if (encoding == null)
        {
            encoding = DefaultEncoding ?? Encoding.UTF8;
        }
        var pos = query.IndexOf("?");

        if (pos >= 0)
        {
            query = query.Substring(pos + 1);
        }
        pos = query.IndexOf("#");
        if (pos >= 0)
        {
            query = query.Substring(0, pos);
        }
        var arr = query.Split('&', '\r', '\n');

        foreach (var item in arr)
        {
            pos = item.IndexOf("=");
            if (pos < 0)
            {
                if (item.Length == 0)
                {
                    continue;
                }
                ListExtensions.Add(this, WebFormat.UrlDecode(item, encoding), string.Empty);
            }
            else
            {
                var key   = item.Substring(0, pos);
                var value = item.Substring(pos + 1);
                if (key.Length == 0 && value.Length == 0)
                {
                    continue;
                }
                ListExtensions.Add(this, WebFormat.UrlDecode(key, encoding), WebFormat.UrlDecode(value, encoding));
            }
        }

        return(arr.Length);
    }