Exemple #1
0
        /// <summary>
        /// Converts any JavaScript value to a primitive number value.
        /// </summary>
        /// <param name="value"> The value to convert. </param>
        /// <returns> A primitive number value. </returns>
        public static double ToNumber(object value)
        {
            if (value == null || value == Undefined.Value)
            {
                return(double.NaN);
            }

            if (value == Null.Value)
            {
                return(+0);
            }

            // Get the type:
            Type valuesType = value.GetType();

            if (valuesType == typeof(double))
            {
                return((double)value);
            }
            if (valuesType == typeof(int))
            {
                return((double)(int)value);
            }
            if (valuesType == typeof(uint))
            {
                return((double)(uint)value);
            }
            if (valuesType == typeof(byte))
            {
                return((double)(byte)value);
            }
            if (valuesType == typeof(sbyte))
            {
                return((double)(sbyte)value);
            }
            if (valuesType == typeof(short))
            {
                return((double)(short)value);
            }
            if (valuesType == typeof(ushort))
            {
                return((double)(ushort)value);
            }
            if (valuesType == typeof(float))
            {
                return((double)(float)value);
            }
            if (valuesType == typeof(bool))
            {
                return((bool)value ? 1 : 0);
            }
            if (valuesType == typeof(string))
            {
                return(NumberParser.CoerceToNumber((string)value));
            }

            // If all else fails, use the string:
            double number = NumberParser.CoerceToNumber(value.ToString());

            if (number == double.NaN)
            {
                throw new ArgumentException("Cannot convert object of type '" + valuesType + "' to a number.", "value");
            }

            return(number);
        }
        /// <summary>
        /// Converts a string to a number (used in type coercion).
        /// </summary>
        /// <returns> The result of parsing the string as a number. </returns>
        internal static double CoerceToNumber(string input)
        {
            var reader = new System.IO.StringReader(input);

            // Skip whitespace and line terminators.
            while (IsWhiteSpaceOrLineTerminator(reader.Peek()))
            {
                reader.Read();
            }

            // Empty strings return 0.
            int firstChar = reader.Read();

            if (firstChar == -1)
            {
                return(0.0);
            }

            // The number can start with a plus or minus sign.
            bool negative = false;

            switch (firstChar)
            {
            case '-':
                negative  = true;
                firstChar = reader.Read();
                break;

            case '+':
                firstChar = reader.Read();
                break;
            }

            // Infinity or -Infinity are also valid.
            if (firstChar == 'I')
            {
                string restOfString1 = reader.ReadToEnd();
                if (restOfString1.StartsWith("nfinity", StringComparison.Ordinal) == true)
                {
                    // Check the end of the string for junk.
                    for (int i = 7; i < restOfString1.Length; i++)
                    {
                        if (IsWhiteSpaceOrLineTerminator(restOfString1[i]) == false)
                        {
                            return(double.NaN);
                        }
                    }
                    return(negative ? double.NegativeInfinity : double.PositiveInfinity);
                }
            }

            // Return NaN if the first digit is not a number or a period.
            if ((firstChar < '0' || firstChar > '9') && firstChar != '.')
            {
                return(double.NaN);
            }

            // Parse the number.
            NumberParser.ParseCoreStatus status;
            double result = NumberParser.ParseCore(reader, (char)firstChar, out status, false);

            // Handle various error cases.
            switch (status)
            {
            case ParseCoreStatus.NoDigits:
            case ParseCoreStatus.NoExponent:
                return(double.NaN);
            }

            // Check the end of the string for junk.
            string restOfString2 = reader.ReadToEnd();

            for (int i = 0; i < restOfString2.Length; i++)
            {
                if (IsWhiteSpaceOrLineTerminator(restOfString2[i]) == false)
                {
                    return(double.NaN);
                }
            }

            return(negative ? -result : result);
        }