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); }
/// <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); } }
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; }