示例#1
0
 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;
         }
     }
 }
示例#2
0
        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;
            }
        }
示例#3
0
        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));
        }
示例#4
0
 public void ContainsTest(string Input, bool Expected)
 {
     Assert.Equal(Expected, StringCommon.Contains(Input, UnicodeCommon.Is_Ascii_Whitespace));
 }
示例#5
0
 public void ContainsDataFilterTest(string Input, bool Expected)
 {
     Assert.Equal(Expected, StringCommon.Contains(Input, FilterWhitespace.Instance));
 }
示例#6
0
 public void ContainsStringTest(string Input, string Match, bool Expected)
 {
     Assert.Equal(Expected, StringCommon.Contains(Input, Match));
 }
示例#7
0
        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!");
            }
        }