Exemple #1
0
        private bool ParsePath(string input, int index, bool onlyPath = false)
        {
            var init = index;

            if ((index < input.Length) &&
                ((input[index] == Symbols.Solidus) || (input[index] == Symbols.ReverseSolidus)))
            {
                index++;
            }

            var paths = new List <string>();

            if (!onlyPath && !string.IsNullOrEmpty(_path) && (index - init == 0))
            {
                var split = _path.Split(Symbols.Solidus);

                if (split.Length > 1)
                {
                    paths.AddRange(split);
                    paths.RemoveAt(split.Length - 1);
                }
            }

            var originalCount = paths.Count;
            var buffer        = Pool.NewStringBuilder();

            while (index <= input.Length)
            {
                var c        = index == input.Length ? Symbols.EndOfFile : input[index];
                var breakNow = !onlyPath && ((c == Symbols.Num) || (c == Symbols.QuestionMark));

                if ((c == Symbols.EndOfFile) || (c == Symbols.Solidus) || (c == Symbols.ReverseSolidus) || breakNow)
                {
                    var path  = buffer.ToString();
                    var close = false;
                    buffer.Clear();

                    if (path.Isi(currentDirectoryAlternative))
                    {
                        path = currentDirectory;
                    }
                    else if (path.Isi(upperDirectoryAlternatives[0]) ||
                             path.Isi(upperDirectoryAlternatives[1]) ||
                             path.Isi(upperDirectoryAlternatives[2]))
                    {
                        path = upperDirectory;
                    }

                    if (path.Is(upperDirectory))
                    {
                        if (paths.Count > 0)
                        {
                            paths.RemoveAt(paths.Count - 1);
                        }

                        close = true;
                    }
                    else if (!path.Is(currentDirectory))
                    {
                        if (_scheme.Is(ProtocolNames.File) &&
                            (paths.Count == originalCount) &&
                            (path.Length == 2) &&
                            path[0].IsLetter() &&
                            (path[1] == Symbols.Pipe))
                        {
                            path = path.Replace(Symbols.Pipe, Symbols.Colon);
                            paths.Clear();
                        }

                        paths.Add(path);
                    }
                    else
                    {
                        close = true;
                    }

                    if (close && (c != Symbols.Solidus) && (c != Symbols.ReverseSolidus))
                    {
                        paths.Add(string.Empty);
                    }

                    if (breakNow)
                    {
                        break;
                    }
                }
                else if ((c == Symbols.Percent) &&
                         (index + 2 < input.Length) &&
                         input[index + 1].IsHex() &&
                         input[index + 2].IsHex())
                {
                    buffer.Append(input[index++]);
                    buffer.Append(input[index++]);
                    buffer.Append(input[index]);
                }
                else if ((c == Symbols.Tab) || (c == Symbols.LineFeed) || (c == Symbols.CarriageReturn))
                {
                    // Parse Error
                }
                else if (c.IsNormalPathCharacter())
                {
                    buffer.Append(c);
                }
                else
                {
                    index += Utf8PercentEncode(buffer, input, index);
                }

                index++;
            }

            buffer.ToPool();
            _path = string.Join("/", paths);

            if (index < input.Length)
            {
                if (input[index] == Symbols.QuestionMark)
                {
                    return(ParseQuery(input, index + 1));
                }

                return(ParseFragment(input, index + 1));
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// The general state.
        /// </summary>
        /// <param name="token">The current token.</param>
        /// <returns>The status.</returns>
        Boolean Data(CssToken token)
        {
            if (token.Type == CssTokenType.AtKeyword)
            {
                switch (((CssKeywordToken)token).Data)
                {
                case RuleNames.MEDIA:
                {
                    AddRule(new CSSMediaRule());
                    SwitchTo(CssState.InMediaList);
                    break;
                }

                case RuleNames.PAGE:
                {
                    AddRule(new CSSPageRule());
                    SwitchTo(CssState.InSelector);
                    break;
                }

                case RuleNames.IMPORT:
                {
                    AddRule(new CSSImportRule());
                    SwitchTo(CssState.BeforeImport);
                    break;
                }

                case RuleNames.FONT_FACE:
                {
                    AddRule(new CSSFontFaceRule());
                    SwitchTo(CssState.InDeclaration);
                    break;
                }

                case RuleNames.CHARSET:
                {
                    AddRule(new CSSCharsetRule());
                    SwitchTo(CssState.BeforeCharset);
                    break;
                }

                case RuleNames.NAMESPACE:
                {
                    AddRule(new CSSNamespaceRule());
                    SwitchTo(CssState.BeforeNamespacePrefix);
                    break;
                }

                case RuleNames.SUPPORTS:
                {
                    buffer = Pool.NewStringBuilder();
                    AddRule(new CSSSupportsRule());
                    SwitchTo(CssState.InCondition);
                    break;
                }

                case RuleNames.KEYFRAMES:
                {
                    AddRule(new CSSKeyframesRule());
                    SwitchTo(CssState.BeforeKeyframesName);
                    break;
                }

                case RuleNames.DOCUMENT:
                {
                    AddRule(new CSSDocumentRule());
                    SwitchTo(CssState.BeforeDocumentFunction);
                    break;
                }

                default:
                {
                    buffer = Pool.NewStringBuilder();
                    AddRule(new CSSUnknownRule());
                    SwitchTo(CssState.InUnknown);
                    InUnknown(token);
                    break;
                }
                }

                return(true);
            }
            else if (token.Type == CssTokenType.CurlyBracketClose)
            {
                return(CloseRule());
            }
            else
            {
                AddRule(new CSSStyleRule());
                SwitchTo(CssState.InSelector);
                InSelector(token);
                return(true);
            }
        }
Exemple #3
0
        private bool ParseAuthority(string input, int index)
        {
            var start  = index;
            var buffer = Pool.NewStringBuilder();
            var user   = default(string);
            var pass   = default(string);

            while (index < input.Length)
            {
                var c = input[index];

                if (c == Symbols.At)
                {
                    if (user == null)
                    {
                        user = buffer.ToString();
                    }
                    else
                    {
                        pass = buffer.ToString();
                    }

                    UserName = user;
                    Password = pass;
                    buffer.Append("%40");
                    start = index + 1;
                }
                else if ((c == Symbols.Colon) && (user == null))
                {
                    user = buffer.ToString();
                    pass = string.Empty;
                    buffer.Clear();
                }
                else if ((c == Symbols.Percent) && (index + 2 < input.Length) && input[index + 1].IsHex() &&
                         input[index + 2].IsHex())
                {
                    buffer.Append(input[index++]).Append(input[index++]).Append(input[index]);
                }
                else if (c.IsOneOf(Symbols.Tab, Symbols.LineFeed, Symbols.CarriageReturn))
                {
                    // Parse Error
                }
                else if (c.IsOneOf(Symbols.Solidus, Symbols.ReverseSolidus, Symbols.Num, Symbols.QuestionMark))
                {
                    break;
                }
                else if ((c != Symbols.Colon) &&
                         ((c == Symbols.Num) || (c == Symbols.QuestionMark) || c.IsNormalPathCharacter()))
                {
                    buffer.Append(c);
                }
                else
                {
                    index += Utf8PercentEncode(buffer, input, index);
                }

                index++;
            }

            buffer.ToPool();
            return(ParseHostName(input, start));
        }
        public Property CreateDeclarationWith(Func<string, Property> createProperty, ref Token token)
        {
            var property = default(Property);

            var sb = Pool.NewStringBuilder();
            var start = token.Position;

            while (token.IsDeclarationName())
            {
                sb.Append(token.ToValue());
                token = NextToken();
            }

            var propertyName = sb.ToPool();

            if (propertyName.Length > 0)
            {
                property = _parser.Options.IncludeUnknownDeclarations ||
                           _parser.Options.AllowInvalidValues
                    ? new UnknownProperty(propertyName)
                    : createProperty(propertyName);

                if (property == null)
                {
                    RaiseErrorOccurred(ParseError.UnknownDeclarationName, start);
                }
                else
                {
                    _nodes.Push(property);
                }

                ParseComments(ref token);

                if (token.Type == TokenType.Colon)
                {
                    bool important;
                    var value = CreateValue(TokenType.CurlyBracketClose, ref token, out important);

                    if (value == null)
                    {
                        RaiseErrorOccurred(ParseError.ValueMissing, token.Position);
                    }
                    else if ((property != null) && property.TrySetValue(value))
                    {
                        property.IsImportant = important;
                    }

                    ParseComments(ref token);
                }
                else
                {
                    RaiseErrorOccurred(ParseError.ColonMissing, token.Position);
                }

                JumpToDeclEnd(ref token);

                if (property != null)
                {
                    _nodes.Pop();
                }
            }
            else if (token.Type != TokenType.EndOfFile)
            {
                RaiseErrorOccurred(ParseError.IdentExpected, start);
                JumpToDeclEnd(ref token);
            }

            if (token.Type == TokenType.Semicolon)
            {
                token = NextToken();
            }

            return property;
        }