public UrlHost(string host) { Value = host; if (ReferenceEquals(null, host) || host.Length <= 0) { Type = EHostType.Empty; } else { Type = EHostType.Opaque; if (StringCommon.Contains(host.AsSpan(), UnicodeCommon.CHAR_FULL_STOP)) { Type = EHostType.Domain; } } }
public AtomicString(ReadOnlyMemory <char> Data, EAtomicStringFlags Flags) { Hash = new CachedValue <int>(() => { if (0 != (Flags & EAtomicStringFlags.CaseInsensitive | EAtomicStringFlags.HasUppercase)) {// This atomic-string wants to always be compared case insensitevly, but has uppercase character in it's string return(StringCommon.Transform(Data, UnicodeCommon.To_ASCII_Lower_Alpha).GetHashCode(StringComparison.InvariantCulture)); } else { //return new string(Data.ToArray()).GetHashCode(); return(Data.Pin().GetHashCode()); } }); Hash_Lower = new CachedValue <int>(() => { /* Check if our string actually has uppercased characters, if it does then we need to lowercase it and get its hash */ if (0 != (Flags & EAtomicStringFlags.HasUppercase)) {// This atomic string has uppercase characters so we do infact need to create the caseless-hash return(StringCommon.Transform(Data, UnicodeCommon.To_ASCII_Lower_Alpha).GetHashCode(StringComparison.Ordinal)); } return(GetHashCode()); }); this.Data = Data; /*this.Data = new Memory<char>(Data.Length); * Data.CopyTo(this.Data);*/ this.Flags = Flags; if (StringCommon.Contains(Data.Span, c => char.IsUpper(c))) { Flags |= EAtomicStringFlags.HasUppercase; } }
private static UnicodeRangeToken Consume_Unicode_Range_Token(DataConsumer <char> Stream) {// SEE: https://www.w3.org/TR/css-syntax-3/#consume-a-unicode-range-token if (Stream is null) { throw new ArgumentNullException(nameof(Stream)); } Contract.EndContractBlock(); // Consume hex and UnicodeCommon.CHAR_QUESTION_MARK digits up to a maximum of 6 if (!Stream.Consume_While(ch => (Is_Ascii_Hex_Digit(ch) || ch == CHAR_QUESTION_MARK), out ReadOnlyMemory <char> Digits, 6)) { throw new CssParserException(ParserErrors.PARSING_FAILED); } if (StringCommon.Contains(Digits.Span, CHAR_QUESTION_MARK)) { string DigitsStr = Digits.Span.ToString(); int Start = Convert.ToInt32(DigitsStr.Replace(CHAR_QUESTION_MARK, CHAR_DIGIT_0), 16); int End = Convert.ToInt32(DigitsStr.Replace(CHAR_QUESTION_MARK, CHAR_F_UPPER), 16); return(new UnicodeRangeToken(Start, End)); } int StartRange = Convert.ToInt32(Digits.ToString(), 16); int EndRange = StartRange; if (Stream.Next == CHAR_HYPHEN_MINUS && Is_Ascii_Hex_Digit(Stream.NextNext)) { Stream.Consume(); // Consume hex digits up to a maximum of 6 if (Stream.Consume_While(Is_Ascii_Hex_Digit, out ReadOnlySpan <char> endDigits, 6)) { EndRange = Convert.ToInt32(endDigits.ToString(), 16); } } return(new UnicodeRangeToken(StartRange, EndRange)); }
public void ContainsTest(string Input, bool Expected) { Assert.Equal(Expected, StringCommon.Contains(Input, UnicodeCommon.Is_Ascii_Whitespace)); }
public void ContainsDataFilterTest(string Input, bool Expected) { Assert.Equal(Expected, StringCommon.Contains(Input, FilterWhitespace.Instance)); }
public void ContainsStringTest(string Input, string Match, bool Expected) { Assert.Equal(Expected, StringCommon.Contains(Input, Match)); }
override public bool Matches(Element E, params Node[] scopeElements) { switch (Operator) { // CSS 2.0 operators case ECssAttributeOperator.Isset: // isset { return(E.hasAttribute(AttributeName)); } case ECssAttributeOperator.Equals: // equals { if (string.IsNullOrEmpty(Value)) { return(false); } return(StringCommon.StrEq(Value, E.getAttribute(AttributeName).AsString())); } case ECssAttributeOperator.PrefixedWith: // equals or prefixed-with { if (!E.hasAttribute(AttributeName)) { return(false); } string val = E.getAttribute(AttributeName).AsString(); if (StringCommon.StrEq(Value, val)) { return(true); } if (val.StartsWith(string.Concat(Value, '-'))) { return(true); } return(false); } case ECssAttributeOperator.Includes: // list-contains { if (string.IsNullOrEmpty(Value)) { return(false); } /* First lets check the elements token-list map */ if (E.tokenListMap.TryGetValue(AttributeName, out IAttributeTokenList listMap)) { var TokenList = (AttributeTokenList <string>)listMap; return(TokenList.Contains(Value)); } if (!E.hasAttribute(AttributeName)) { return(false); } var attr = E.getAttribute(AttributeName); var set = DOMCommon.Parse_Ordered_Set(attr.AsAtomic().AsMemory()); return(set.Contains(Value.AsMemory())); } // Sub-string operators case ECssAttributeOperator.StartsWith: // starts-with { if (string.IsNullOrEmpty(Value)) { return(false); } if (!E.hasAttribute(AttributeName)) { return(false); } var attr = E.getAttribute(AttributeName); return(attr.AsString().StartsWith(Value)); } case ECssAttributeOperator.EndsWith: // ends-with { if (string.IsNullOrEmpty(Value)) { return(false); } if (!E.hasAttribute(AttributeName)) { return(false); } var attr = E.getAttribute(AttributeName); return(attr.AsString().EndsWith(Value)); } case ECssAttributeOperator.Contains: // contains { if (string.IsNullOrEmpty(Value)) { return(false); } if (!E.hasAttribute(AttributeName)) { return(false); } var attr = E.getAttribute(AttributeName); return(StringCommon.Contains(attr.AsAtomic().AsMemory().Span, Value.AsMemory().Span)); } default: throw new CssSelectorException($"Attribute selector operator ({Enum.GetName(typeof(ECssAttributeOperator), Operator)}) logic not implemented!"); } }