public static PropertyValue ParseNumber(BufferString value, NumberParseFlags parseFlags)
        {
            bool  flag   = false;
            bool  flag2  = false;
            bool  flag3  = false;
            ulong num    = 0uL;
            int   num2   = 0;
            int   num3   = 0;
            bool  flag4  = false;
            int   num4   = 0;
            int   length = value.Length;

            while (num4 < length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[num4])))
            {
                num4++;
            }
            if (num4 == length)
            {
                return(PropertyValue.Null);
            }
            if (num4 < length && (value[num4] == '-' || value[num4] == '+'))
            {
                flag2 = true;
                flag3 = (value[num4] == '-');
                num4++;
            }
            while (num4 < length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[num4])))
            {
                flag = true;
                if (num < 1844674407370955152uL)
                {
                    num = num * 10uL + (ulong)(value[num4] - '0');
                }
                else
                {
                    num2++;
                }
                num4++;
            }
            if (num4 < length && value[num4] == '.')
            {
                flag4 = true;
                num4++;
                while (num4 < length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[num4])))
                {
                    flag = true;
                    if (num < 1844674407370955152uL)
                    {
                        num = num * 10uL + (ulong)(value[num4] - '0');
                        num2--;
                    }
                    num4++;
                }
                if (num2 >= 0 && (parseFlags & NumberParseFlags.Strict) != 0)
                {
                    return(PropertyValue.Null);
                }
            }
            if (!flag)
            {
                return(PropertyValue.Null);
            }
            while (num4 < length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[num4])))
            {
                num4++;
            }
            if (num4 < length && (value[num4] | ' ') == 'e' && num4 + 1 < length && (value[num4 + 1] == '-' || value[num4 + 1] == '+' || ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[num4 + 1]))))
            {
                flag4 = true;
                num4++;
                bool flag5 = false;
                if (value[num4] == '-' || value[num4] == '+')
                {
                    flag5 = (value[num4] == '-');
                    num4++;
                }
                while (num4 < length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[num4])))
                {
                    num3 = num3 * 10 + (value[num4++] - '0');
                }
                if (flag5)
                {
                    num3 = -num3;
                }
                while (num4 < length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[num4])))
                {
                    num4++;
                }
            }
            uint         num5         = flag4 ? 10000u : 1u;
            uint         num6         = 1u;
            PropertyType propertyType = flag4 ? PropertyType.Fractional : PropertyType.Integer;
            bool         flag6        = false;
            int          num7         = 0;

            if (num4 + 1 < length)
            {
                if ((value[num4] | ' ') == 'p')
                {
                    if ((value[num4 + 1] | ' ') == 'c')
                    {
                        num5         = 1920u;
                        num6         = 1u;
                        flag6        = true;
                        propertyType = PropertyType.AbsLength;
                        num7         = 2;
                    }
                    else if ((value[num4 + 1] | ' ') == 't')
                    {
                        num5         = 160u;
                        num6         = 1u;
                        flag6        = true;
                        propertyType = PropertyType.AbsLength;
                        num7         = 2;
                    }
                    else if ((value[num4 + 1] | ' ') == 'x')
                    {
                        num5         = 11520u;
                        num6         = 120u;
                        propertyType = PropertyType.Pixels;
                        flag6        = true;
                        num7         = 2;
                    }
                }
                else if ((value[num4] | ' ') == 'e')
                {
                    if ((value[num4 + 1] | ' ') == 'm')
                    {
                        num5         = 160u;
                        num6         = 1u;
                        propertyType = PropertyType.Ems;
                        flag6        = true;
                        num7         = 2;
                    }
                    else if ((value[num4 + 1] | ' ') == 'x')
                    {
                        num5         = 160u;
                        num6         = 1u;
                        propertyType = PropertyType.Exs;
                        flag6        = true;
                        num7         = 2;
                    }
                }
                else if ((value[num4] | ' ') == 'i')
                {
                    if ((value[num4 + 1] | ' ') == 'n')
                    {
                        num5         = 11520u;
                        num6         = 1u;
                        flag6        = true;
                        propertyType = PropertyType.AbsLength;
                        num7         = 2;
                    }
                }
                else if ((value[num4] | ' ') == 'c')
                {
                    if ((value[num4 + 1] | ' ') == 'm')
                    {
                        num5         = 1152000u;
                        num6         = 254u;
                        flag6        = true;
                        propertyType = PropertyType.AbsLength;
                        num7         = 2;
                    }
                }
                else if ((value[num4] | ' ') == 'm' && (value[num4 + 1] | ' ') == 'm')
                {
                    num5         = 115200u;
                    num6         = 254u;
                    flag6        = true;
                    propertyType = PropertyType.AbsLength;
                    num7         = 2;
                }
            }
            if (!flag6 && num4 < length)
            {
                if (value[num4] == '%')
                {
                    num5         = 10000u;
                    num6         = 1u;
                    propertyType = PropertyType.Percentage;
                    num7         = 1;
                }
                else if (value[num4] == '*')
                {
                    num5         = 1u;
                    num6         = 1u;
                    propertyType = PropertyType.Multiple;
                    num7         = 1;
                }
            }
            num4 += num7;
            if (num4 < length)
            {
                while (num4 < length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[num4])))
                {
                    num4++;
                }
                if (num4 < length && (parseFlags & (NumberParseFlags.StyleSheetProperty | NumberParseFlags.Strict)) != 0)
                {
                    return(PropertyValue.Null);
                }
            }
            if (num != 0uL)
            {
                int num8 = num2 + num3;
                if (num8 > 0)
                {
                    if (num8 > 20)
                    {
                        num8 = 0;
                        num  = 18446744073709551615uL;
                    }
                    else
                    {
                        while (num8 != 0)
                        {
                            if (num > 1844674407370955161uL)
                            {
                                num8 = 0;
                                num  = 18446744073709551615uL;
                                break;
                            }
                            num *= 10uL;
                            num8--;
                        }
                    }
                }
                else if (num8 < -10)
                {
                    if (num8 < -21)
                    {
                        num8 = 0;
                        num  = 0uL;
                    }
                    else
                    {
                        while (num8 != -10)
                        {
                            num /= 10uL;
                            num8++;
                        }
                    }
                }
                num *= num5;
                num /= num6;
                while (num8 != 0)
                {
                    num /= 10uL;
                    num8++;
                }
                if (num > 67108863uL)
                {
                    num = 67108863uL;
                }
            }
            int num9 = (int)num;

            if (flag3)
            {
                num9 = -num9;
            }
            if (propertyType == PropertyType.Integer)
            {
                if ((parseFlags & NumberParseFlags.Integer) == 0)
                {
                    if ((parseFlags & NumberParseFlags.HtmlFontUnits) != 0)
                    {
                        if (flag2)
                        {
                            if (num9 < -7)
                            {
                                num9 = -7;
                            }
                            else if (num9 > 7)
                            {
                                num9 = 7;
                            }
                            propertyType = PropertyType.RelHtmlFontUnits;
                        }
                        else
                        {
                            if (num9 < 1)
                            {
                                num9 = 1;
                            }
                            else if (num9 > 7)
                            {
                                num9 = 7;
                            }
                            propertyType = PropertyType.HtmlFontUnits;
                        }
                    }
                    else if ((parseFlags & NumberParseFlags.AbsoluteLength) != 0)
                    {
                        num = num * 11520uL / 120uL;
                        if (num > 67108863uL)
                        {
                            num = 67108863uL;
                        }
                        num9 = (int)num;
                        if (flag3)
                        {
                            num9 = -num9;
                        }
                        propertyType = PropertyType.Pixels;
                    }
                    else
                    {
                        if ((parseFlags & NumberParseFlags.Float) == 0)
                        {
                            return(PropertyValue.Null);
                        }
                        num *= 10000uL;
                        if (num > 67108863uL)
                        {
                            num = 67108863uL;
                        }
                        num9 = (int)num;
                        if (flag3)
                        {
                            num9 = -num9;
                        }
                        propertyType = PropertyType.Fractional;
                    }
                }
            }
            else if (propertyType == PropertyType.Fractional)
            {
                if ((parseFlags & NumberParseFlags.Float) == 0)
                {
                    if ((parseFlags & NumberParseFlags.AbsoluteLength) == 0)
                    {
                        return(PropertyValue.Null);
                    }
                    num = num * 11520uL / 120uL / 10000uL;
                    if (num > 67108863uL)
                    {
                        num = 67108863uL;
                    }
                    num9 = (int)num;
                    if (flag3)
                    {
                        num9 = -num9;
                    }
                    propertyType = PropertyType.Pixels;
                }
            }
            else if (propertyType == PropertyType.AbsLength || propertyType == PropertyType.Pixels)
            {
                if ((parseFlags & NumberParseFlags.AbsoluteLength) == 0)
                {
                    return(PropertyValue.Null);
                }
            }
            else if (propertyType == PropertyType.Ems || propertyType == PropertyType.Exs)
            {
                if ((parseFlags & NumberParseFlags.EmExLength) == 0)
                {
                    return(PropertyValue.Null);
                }
            }
            else if (propertyType == PropertyType.Percentage)
            {
                if ((parseFlags & NumberParseFlags.Percentage) == 0)
                {
                    return(PropertyValue.Null);
                }
            }
            else if (propertyType == PropertyType.Multiple && (parseFlags & NumberParseFlags.Multiple) == 0)
            {
                return(PropertyValue.Null);
            }
            if (num9 < 0 && (parseFlags & NumberParseFlags.NonNegative) != 0 && propertyType != PropertyType.RelHtmlFontUnits)
            {
                return(PropertyValue.Null);
            }
            return(new PropertyValue(propertyType, num9));
        }
Example #2
0
        public static PropertyValue ParseNumber(BufferString value, NumberParseFlags parseFlags)
        {
            bool  isValidNumber      = false;
            bool  isSigned           = false;
            bool  isNegative         = false;
            ulong result             = 0;
            int   exponent           = 0;
            int   scientificExponent = 0;
            bool  floatNumber        = false;
            int   offset             = 0;
            int   end = value.Length;

            while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))
            {
                offset++;
            }

            if (offset == end)
            {
                return(PropertyValue.Null);
            }

            if (offset < end && (value[offset] == '-' || value[offset] == '+'))
            {
                isSigned   = true;
                isNegative = (value[offset] == '-');
                offset++;
            }

            while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset])))
            {
                isValidNumber = true;
                if (result < ulong.MaxValue / 10 - 9)
                {
                    result = unchecked (result * 10u + (uint)(value[offset] - '0'));
                }
                else
                {
                    exponent++;
                }
                offset++;
            }

            if (offset < end && value[offset] == '.')
            {
                floatNumber = true;
                offset++;

                while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset])))
                {
                    isValidNumber = true;

                    if (result < ulong.MaxValue / 10 - 9)
                    {
                        result = unchecked (result * 10u + (uint)(value[offset] - '0'));
                        exponent--;
                    }

                    offset++;
                }

                if (exponent >= 0 && 0 != (parseFlags & NumberParseFlags.Strict))
                {
                    return(PropertyValue.Null);
                }
            }

            if (!isValidNumber)
            {
                return(PropertyValue.Null);
            }

            while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))
            {
                offset++;
            }

            if (offset < end && (value[offset] | '\x20') == 'e')
            {
                if (offset + 1 < end && (value[offset + 1] == '-' || value[offset + 1] == '+' || ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset + 1]))))
                {
                    floatNumber = true;
                    offset++;

                    bool isNegativeScientificExponent = false;

                    if (value[offset] == '-' || value[offset] == '+')
                    {
                        isNegativeScientificExponent = (value[offset] == '-');
                        offset++;
                    }

                    while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset])))
                    {
                        scientificExponent = unchecked (scientificExponent * 10 + (value[offset++] - '0'));
                    }

                    if (isNegativeScientificExponent)
                    {
                        scientificExponent = -scientificExponent;
                    }

                    while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))
                    {
                        offset++;
                    }
                }
            }

            uint         mul        = floatNumber ? 10000u : 1;
            uint         div        = 1;
            PropertyType units      = floatNumber ? PropertyType.Fractional : PropertyType.Integer;
            bool         recognized = false;
            int          typeLength = 0;

            if (offset + 1 < end)
            {
                if ((value[offset] | '\x20') == 'p')
                {
                    if ((value[offset + 1] | '\x20') == 'c')
                    {
                        mul        = 8 * 20 * 12;
                        div        = 1;
                        recognized = true;
                        units      = PropertyType.AbsLength;
                        typeLength = 2;
                    }
                    else if ((value[offset + 1] | '\x20') == 't')
                    {
                        mul        = 8 * 20;
                        div        = 1;
                        recognized = true;
                        units      = PropertyType.AbsLength;
                        typeLength = 2;
                    }
                    else if ((value[offset + 1] | '\x20') == 'x')
                    {
                        mul        = 8 * 20 * 72;
                        div        = 120;
                        units      = PropertyType.Pixels;
                        recognized = true;
                        typeLength = 2;
                    }
                }
                else if ((value[offset] | '\x20') == 'e')
                {
                    if ((value[offset + 1] | '\x20') == 'm')
                    {
                        mul        = 8 * 20;
                        div        = 1;
                        units      = PropertyType.Ems;
                        recognized = true;
                        typeLength = 2;
                    }
                    else if ((value[offset + 1] | '\x20') == 'x')
                    {
                        mul        = 8 * 20;
                        div        = 1;
                        units      = PropertyType.Exs;
                        recognized = true;
                        typeLength = 2;
                    }
                }
                else if ((value[offset] | '\x20') == 'i')
                {
                    if ((value[offset + 1] | '\x20') == 'n')
                    {
                        mul        = 8 * 20 * 72;
                        div        = 1;
                        recognized = true;
                        units      = PropertyType.AbsLength;
                        typeLength = 2;
                    }
                }
                else if ((value[offset] | '\x20') == 'c')
                {
                    if ((value[offset + 1] | '\x20') == 'm')
                    {
                        mul        = 8 * 20 * 72 * 100;
                        div        = 254;
                        recognized = true;
                        units      = PropertyType.AbsLength;
                        typeLength = 2;
                    }
                }
                else if ((value[offset] | '\x20') == 'm')
                {
                    if ((value[offset + 1] | '\x20') == 'm')
                    {
                        mul        = 8 * 20 * 72 * 10;
                        div        = 254;
                        recognized = true;
                        units      = PropertyType.AbsLength;
                        typeLength = 2;
                    }
                }
            }

            if (!recognized && offset < end)
            {
                if (value[offset] == '%')
                {
                    mul        = 10000;
                    div        = 1;
                    units      = PropertyType.Percentage;
                    recognized = true;
                    typeLength = 1;
                }
                else if (value[offset] == '*')
                {
                    mul        = 1;
                    div        = 1;
                    units      = PropertyType.Multiple;
                    recognized = true;
                    typeLength = 1;
                }
            }

            offset += typeLength;

            if (offset < end)
            {
                while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))
                {
                    offset++;
                }

                if (offset < end)
                {
                    if (0 != (parseFlags & (NumberParseFlags.Strict | NumberParseFlags.StyleSheetProperty)))
                    {
                        return(PropertyValue.Null);
                    }
                }
            }

            if (result != 0)
            {
                int actualExponent = exponent + scientificExponent;

                if (actualExponent > 0)
                {
                    if (actualExponent > 20)
                    {
                        actualExponent = 0;
                        result         = ulong.MaxValue;
                    }
                    else
                    {
                        while (actualExponent != 0)
                        {
                            if (result > ulong.MaxValue / 10)
                            {
                                actualExponent = 0;
                                result         = ulong.MaxValue;
                                break;
                            }
                            else
                            {
                                result = unchecked (result * 10);
                            }
                            actualExponent--;
                        }
                    }
                }
                else if (actualExponent < -10)
                {
                    if (actualExponent < -21)
                    {
                        actualExponent = 0;
                        result         = 0;
                    }
                    else
                    {
                        while (actualExponent != -10)
                        {
                            result /= 10;
                            actualExponent++;
                        }
                    }
                }

                result *= mul;
                result /= div;

                while (actualExponent != 0)
                {
                    result /= 10;
                    actualExponent++;
                }

                if (result > PropertyValue.ValueMax)
                {
                    result = PropertyValue.ValueMax;
                }
            }

            int intValue = unchecked ((int)result);

            if (isNegative)
            {
                intValue = -intValue;
            }

            if (units == PropertyType.Integer)
            {
                if (0 != (parseFlags & NumberParseFlags.Integer))
                {
                }
                else if (0 != (parseFlags & NumberParseFlags.HtmlFontUnits))
                {
                    if (isSigned)
                    {
                        if (intValue < -7)
                        {
                            intValue = -7;
                        }
                        else if (intValue > 7)
                        {
                            intValue = 7;
                        }
                        units = PropertyType.RelHtmlFontUnits;
                    }
                    else
                    {
                        if (intValue < 1)
                        {
                            intValue = 1;
                        }
                        else if (intValue > 7)
                        {
                            intValue = 7;
                        }
                        units = PropertyType.HtmlFontUnits;
                    }
                }
                else if (0 != (parseFlags & NumberParseFlags.AbsoluteLength))
                {
                    result = result * (8 * 20 * 72) / 120;
                    if (result > PropertyValue.ValueMax)
                    {
                        result = PropertyValue.ValueMax;
                    }

                    intValue = unchecked ((int)result);
                    if (isNegative)
                    {
                        intValue = -intValue;
                    }

                    units = PropertyType.Pixels;
                }
                else if (0 != (parseFlags & NumberParseFlags.Float))
                {
                    result *= 10000;
                    if (result > PropertyValue.ValueMax)
                    {
                        result = PropertyValue.ValueMax;
                    }

                    intValue = unchecked ((int)result);
                    if (isNegative)
                    {
                        intValue = -intValue;
                    }

                    units = PropertyType.Fractional;
                }
                else
                {
                    return(PropertyValue.Null);
                }
            }
            else if (units == PropertyType.Fractional)
            {
                if (0 != (parseFlags & NumberParseFlags.Float))
                {
                }
                else if (0 != (parseFlags & NumberParseFlags.AbsoluteLength))
                {
                    result = result * (8 * 20 * 72) / 120 / 10000;
                    if (result > PropertyValue.ValueMax)
                    {
                        result = PropertyValue.ValueMax;
                    }

                    intValue = unchecked ((int)result);
                    if (isNegative)
                    {
                        intValue = -intValue;
                    }

                    units = PropertyType.Pixels;
                }
                else
                {
                    return(PropertyValue.Null);
                }
            }
            else if (units == PropertyType.AbsLength || units == PropertyType.Pixels)
            {
                if (0 == (parseFlags & NumberParseFlags.AbsoluteLength))
                {
                    return(PropertyValue.Null);
                }
            }
            else if (units == PropertyType.Ems || units == PropertyType.Exs)
            {
                if (0 == (parseFlags & NumberParseFlags.EmExLength))
                {
                    return(PropertyValue.Null);
                }
            }
            else if (units == PropertyType.Percentage)
            {
                if (0 == (parseFlags & NumberParseFlags.Percentage))
                {
                    return(PropertyValue.Null);
                }
            }
            else if (units == PropertyType.Multiple)
            {
                if (0 == (parseFlags & NumberParseFlags.Multiple))
                {
                    return(PropertyValue.Null);
                }
            }

            if (intValue < 0 && 0 != (parseFlags & NumberParseFlags.NonNegative) && units != PropertyType.RelHtmlFontUnits)
            {
                return(PropertyValue.Null);
            }

            return(new PropertyValue(units, intValue));
        }