Example #1
0
        public static void Consume_Number(DataConsumer <char> Stream, out ReadOnlyMemory <char> /*  */ outResult, out object outNumber, out ENumericTokenType outType)
        {/* Docs: https://www.w3.org/TR/css-syntax-3/#consume-number */
            if (Stream is null)
            {
                throw new ArgumentNullException(nameof(Stream));
            }
            Contract.EndContractBlock();

            outType = ENumericTokenType.Integer;

            bool IsPositive          = true;
            bool Exponent_IsPositive = true;
            bool Decimal             = false;
            bool HasExponent         = false;

            int Start = Stream.Position;

            if (Stream.Next == CHAR_HYPHEN_MINUS)
            {
                IsPositive = false;
                Stream.Consume();
            }
            else if (Stream.Next == CHAR_PLUS_SIGN)
            {
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Integer))
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            if (Stream.Next == CHAR_FULL_STOP)
            {
                outType = ENumericTokenType.Number;
                Decimal = true;
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Fraction) && Decimal)
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            if (Stream.Next == CHAR_E_UPPER || Stream.Next == CHAR_E_LOWER)
            {
                HasExponent = true;
                outType     = ENumericTokenType.Number;
                Stream.Consume();
            }

            if (Stream.Next == CHAR_HYPHEN_MINUS)
            {
                Exponent_IsPositive = false;
                Stream.Consume();
            }
            else if (Stream.Next == CHAR_PLUS_SIGN)
            {
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Exponent) && HasExponent)
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            int len = Stream.Position - Start;

            outResult = Stream.AsMemory().Slice(Start, len);

            //return S * (I + (F * Math.Pow(10, -D))) * Math.Pow(10, T*E);
            if (Decimal)
            {
                outNumber = ParsingCommon.ToDecimal(IsPositive ? 1 : -1, Integer, Fraction, Exponent_IsPositive ? 1 : -1, Exponent);
            }
            else
            {
                outNumber = ParsingCommon.ToInteger(IsPositive ? 1 : -1, Integer, Exponent_IsPositive ? 1 : -1, Exponent);
            }
        }
Example #2
0
        public static double Convert_String_To_Number(DataConsumer <char> Stream)
        {/* Docs: https://www.w3.org/TR/css-syntax-3/#convert-string-to-number */
            if (Stream is null)
            {
                throw new ArgumentNullException(nameof(Stream));
            }
            Contract.EndContractBlock();

            //double S = 1;//Sign
            //double T = 1;// Exponent Sign
            //double I = 0;// Integer
            //double F = 0;// Fraction
            //double D = 0;// Number of fraction digits
            //double E = 0;// Exponent

            bool Sign          = true;
            bool Exponent_Sign = true;
            bool Decimal       = false;

            //bool Exponent_Indicator = false;


            if (Stream.Next == CHAR_HYPHEN_MINUS)
            {
                //S = -1;
                Sign = false;
                Stream.Consume();
            }
            else if (Stream.Next == CHAR_PLUS_SIGN)
            {
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Integer))
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            if (Stream.Next == CHAR_FULL_STOP)
            {
                Decimal = true;
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Fraction))
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            if (Stream.Next == CHAR_E_UPPER || Stream.Next == CHAR_E_LOWER)
            {
                //Exponent_Indicator = true;
                Stream.Consume();
            }

            if (Stream.Next == CHAR_HYPHEN_MINUS)
            {
                //T = -1;
                Exponent_Sign = false;
                Stream.Consume();
            }
            else if (Stream.Next == CHAR_PLUS_SIGN)
            {
                Stream.Consume();
            }

            if (!Stream.Consume_While(Is_Ascii_Digit, out ReadOnlySpan <char> Exponent))
            {
                throw new CssParserException(ParserErrors.PARSING_FAILED);
            }

            //return S * (I + (F * Math.Pow(10, -D))) * Math.Pow(10, T*E);
            if (Decimal)
            {
                return(ParsingCommon.ToDecimal(Sign ? 1 : -1, Integer, Fraction, Exponent_Sign ? 1 : -1, Exponent));
            }
            else
            {
                return(ParsingCommon.ToInteger(Sign ? 1 : -1, Integer, Exponent_Sign ? 1 : -1, Exponent));
            }
        }