IsWhiteSpace() public static method

public static IsWhiteSpace ( char c ) : bool
c char
return bool
コード例 #1
0
        internal static bool Parse(string s, bool tryParse, out int result, out Exception exc)
        {
            int  val = 0;
            int  len;
            int  i, sign = 1;
            bool digits_seen = false;

            result = 0;
            exc    = null;
            NumberFormatInfo nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s [i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            var ps_length = nfi.PositiveSign.Length;
            var ns_length = nfi.NegativeSign.Length;

            if (len > ps_length && string.CompareOrdinalUnchecked(s, i, ns_length, nfi.PositiveSign, 0, ps_length) == 0)
            {
                i += ps_length;
            }
            else if (len > ns_length && string.CompareOrdinalUnchecked(s, i, ns_length, nfi.NegativeSign, 0, ns_length) == 0)
            {
                sign = -1;
                i   += ns_length;
            }

            for (; i < len; i++)
            {
                c = s [i];

                if (c == '\0')
                {
                    i = len;
                    continue;
                }

                if (c >= '0' && c <= '9')
                {
                    byte d = (byte)(c - '0');

                    if (val > (MaxValue / 10))
                    {
                        goto overflow;
                    }

                    if (val == (MaxValue / 10))
                    {
                        if ((d > (MaxValue % 10)) && (sign == 1 || (d > ((MaxValue % 10) + 1))))
                        {
                            goto overflow;
                        }
                        if (sign == -1)
                        {
                            val = (val * sign * 10) - d;
                        }
                        else
                        {
                            val = (val * 10) + d;
                        }

                        if (ProcessTrailingWhitespace(tryParse, s, i + 1, ref exc))
                        {
                            result = val;
                            return(true);
                        }
                        goto overflow;
                    }
                    else
                    {
                        val = val * 10 + d;
                    }

                    digits_seen = true;
                }
                else if (!ProcessTrailingWhitespace(tryParse, s, i, ref exc))
                {
                    return(false);
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            if (sign == -1)
            {
                result = val * sign;
            }
            else
            {
                result = val;
            }

            return(true);

overflow:
            if (!tryParse)
            {
                exc = new OverflowException("Value is too large");
            }
            return(false);
        }
コード例 #2
0
        internal static bool Parse(string s, bool tryParse, out uint result, out Exception exc)
        {
            uint val = 0;
            int  len;
            int  i;
            bool digits_seen       = false;
            bool has_negative_sign = false;

            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s [i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            if (s [i] == '+')
            {
                i++;
            }
            else if (s[i] == '-')
            {
                i++;
                has_negative_sign = true;
            }

            for (; i < len; i++)
            {
                c = s [i];

                if (c >= '0' && c <= '9')
                {
                    uint d = (uint)(c - '0');

                    if ((val > MaxValue / 10) || (val == (MaxValue / 10) && d > (MaxValue % 10)))
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException(Locale.GetText("Value is too large"));
                        }
                        return(false);
                    }
                    val         = (val * 10) + d;
                    digits_seen = true;
                }
                else if (!Int32.ProcessTrailingWhitespace(tryParse, s, i, ref exc))
                {
                    return(false);
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            // -0 is legal but other negative values are not
            if (has_negative_sign && (val > 0))
            {
                if (!tryParse)
                {
                    exc = new OverflowException(
                        Locale.GetText("Negative number"));
                }
                return(false);
            }

            result = val;
            return(true);
        }
コード例 #3
0
        internal static bool Parse(string s, bool tryParse, out sbyte result, out Exception exc)
        {
            int  ival = 0;
            int  len;
            int  i;
            bool neg         = false;
            bool digits_seen = false;

            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s[i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = IntParser.GetFormatException();
                }
                return(false);
            }

            c = s[i];
            if (c == '+')
            {
                i++;
            }
            else if (c == '-')
            {
                neg = true;
                i++;
            }

            for (; i < len; i++)
            {
                c = s[i];

                if (c >= '0' && c <= '9')
                {
                    if (tryParse)
                    {
                        int intval = ival * 10 - (int)(c - '0');

                        if (intval < MinValue)
                        {
                            return(false);
                        }
                        ival = (sbyte)intval;
                    }
                    else
                    {
                        ival = checked (ival * 10 - (int)(c - '0'));
                    }
                    digits_seen = true;
                }
                else
                {
                    if (Char.IsWhiteSpace(c))
                    {
                        for (i++; i < len; i++)
                        {
                            if (!Char.IsWhiteSpace(s[i]))
                            {
                                if (!tryParse)
                                {
                                    exc = IntParser.GetFormatException();
                                }
                                return(false);
                            }
                        }
                        break;
                    }
                    else
                    {
                        if (!tryParse)
                        {
                            exc = IntParser.GetFormatException();
                        }
                        return(false);
                    }
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = IntParser.GetFormatException();
                }
                return(false);
            }

            ival = neg ? ival : -ival;
            if (ival < MinValue || ival > MaxValue)
            {
                if (!tryParse)
                {
                    exc = new OverflowException();
                }
                return(false);
            }

            result = (sbyte)ival;
            return(true);
        }
コード例 #4
0
        private static bool TryParseEnum(Type enumType, String value, bool ignoreCase, ref EnumResult parseResult)
        {
            if (enumType == null)
            {
                throw new ArgumentNullException(nameof(enumType));
            }
            Contract.EndContractBlock();

            RuntimeType rtType = enumType as RuntimeType;

            if (rtType == null)
            {
                throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
            }

            if (!enumType.IsEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
            }

            if (value == null)
            {
                parseResult.SetFailure(ParseFailureKind.ArgumentNull, nameof(value));
                return(false);
            }

            int firstNonWhitespaceIndex = -1;

            for (int i = 0; i < value.Length; i++)
            {
                if (!Char.IsWhiteSpace(value[i]))
                {
                    firstNonWhitespaceIndex = i;
                    break;
                }
            }
            if (firstNonWhitespaceIndex == -1)
            {
                parseResult.SetFailure(ParseFailureKind.Argument, nameof(SR.Arg_MustContainEnumInfo), null);
                return(false);
            }

            // We have 2 code paths here. One if they are values else if they are Strings.
            // values will have the first character as as number or a sign.
            ulong result = 0;

            char firstNonWhitespaceChar = value[firstNonWhitespaceIndex];

            if (Char.IsDigit(firstNonWhitespaceChar) || firstNonWhitespaceChar == '-' || firstNonWhitespaceChar == '+')
            {
                Type   underlyingType = GetUnderlyingType(enumType);
                Object temp;

                try
                {
                    value = value.Trim();
                    temp  = Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture);
                    parseResult.parsedEnum = ToObject(enumType, temp);
                    return(true);
                }
                catch (FormatException)
                { // We need to Parse this as a String instead. There are cases
                  // when you tlbimp enums that can have values of the form "3D".
                  // Don't fix this code.
                }
                catch (Exception ex)
                {
                    if (parseResult.canThrow)
                    {
                        throw;
                    }
                    else
                    {
                        parseResult.SetFailure(ex);
                        return(false);
                    }
                }
            }

            // Find the field. Let's assume that these are always static classes
            // because the class is an enum.
            TypeValuesAndNames entry = GetCachedValuesAndNames(rtType, true);

            String[] enumNames  = entry.Names;
            ulong[]  enumValues = entry.Values;

            StringComparison comparison = ignoreCase ?
                                          StringComparison.OrdinalIgnoreCase :
                                          StringComparison.Ordinal;

            int valueIndex = firstNonWhitespaceIndex;

            while (valueIndex <= value.Length) // '=' is to handle invalid case of an ending comma
            {
                // Find the next separator, if there is one, otherwise the end of the string.
                int endIndex = value.IndexOf(enumSeparatorChar, valueIndex);
                if (endIndex == -1)
                {
                    endIndex = value.Length;
                }

                // Shift the starting and ending indices to eliminate whitespace
                int endIndexNoWhitespace = endIndex;
                while (valueIndex < endIndex && Char.IsWhiteSpace(value[valueIndex]))
                {
                    valueIndex++;
                }
                while (endIndexNoWhitespace > valueIndex && Char.IsWhiteSpace(value[endIndexNoWhitespace - 1]))
                {
                    endIndexNoWhitespace--;
                }
                int valueSubstringLength = endIndexNoWhitespace - valueIndex;

                // Try to match this substring against each enum name
                bool success = false;
                for (int i = 0; i < enumNames.Length; i++)
                {
                    if (enumNames[i].Length == valueSubstringLength &&
                        string.Compare(enumNames[i], 0, value, valueIndex, valueSubstringLength, comparison) == 0)
                    {
                        result |= enumValues[i];
                        success = true;
                        break;
                    }
                }

                // If we couldn't find a match, throw an argument exception.
                if (!success)
                {
                    // Not found, throw an argument exception.
                    parseResult.SetFailure(ParseFailureKind.ArgumentWithParameter, nameof(SR.Arg_EnumValueNotFound), value);
                    return(false);
                }

                // Move our pointer to the ending index to go again.
                valueIndex = endIndex + 1;
            }

            try
            {
                parseResult.parsedEnum = ToObject(enumType, result);
                return(true);
            }
            catch (Exception ex)
            {
                if (parseResult.canThrow)
                {
                    throw;
                }
                else
                {
                    parseResult.SetFailure(ex);
                    return(false);
                }
            }
        }
コード例 #5
0
ファイル: TypeNameParser.cs プロジェクト: lizhou0613/mono
        // Ported from the C version in mono_reflection_parse_type ()
        static ParsedName ParseName(string name, bool recursed, int pos, out int end_pos)
        {
            end_pos = 0;

            while (pos < name.Length && name [pos] == ' ')
            {
                pos++;
            }

            var res = new ParsedName()
            {
                Names = new List <string> ()
            };

            int  start        = pos;
            int  name_start   = pos;
            bool in_modifiers = false;

            while (pos < name.Length)
            {
                switch (name [pos])
                {
                case '+':
                    res.Names.Add(name.Substring(name_start, pos - name_start));
                    name_start = pos + 1;
                    break;

                case '\\':
                    pos++;
                    break;

                case '&':
                case '*':
                case '[':
                case ',':
                case ']':
                    in_modifiers = true;
                    break;

                default:
                    break;
                }
                if (in_modifiers)
                {
                    break;
                }
                pos++;
            }

            if (res.Names.Count == 0)
            {
                res.Names.Add(name.Substring(name_start, pos - name_start));
            }

            bool isbyref = false;
            bool isptr   = false;
            int  rank    = -1;

            bool end = false;

            while (pos < name.Length && !end)
            {
                switch (name [pos])
                {
                case '&':
                    if (isbyref)
                    {
                        return(null);
                    }
                    pos++;
                    isbyref = true;
                    isptr   = false;
                    if (res.Modifiers == null)
                    {
                        res.Modifiers = new List <int> ();
                    }
                    res.Modifiers.Add(0);
                    break;

                case '*':
                    if (isbyref)
                    {
                        return(null);
                    }
                    pos++;
                    if (res.Modifiers == null)
                    {
                        res.Modifiers = new List <int> ();
                    }
                    res.Modifiers.Add(-1);
                    isptr = true;
                    break;

                case '[':
                    // An array or generic arguments
                    if (isbyref)
                    {
                        return(null);
                    }
                    pos++;
                    if (pos == name.Length)
                    {
                        return(null);
                    }

                    if (name [pos] == ',' || name [pos] == '*' || name [pos] == ']')
                    {
                        // Array
                        bool bounded = false;
                        isptr = false;
                        rank  = 1;
                        while (pos < name.Length)
                        {
                            if (name [pos] == ']')
                            {
                                break;
                            }
                            if (name [pos] == ',')
                            {
                                rank++;
                            }
                            else if (name [pos] == '*')                             /* '*' means unknown lower bound */
                            {
                                bounded = true;
                            }
                            else
                            {
                                return(null);
                            }
                            pos++;
                        }
                        if (pos == name.Length)
                        {
                            return(null);
                        }
                        if (name [pos] != ']')
                        {
                            return(null);
                        }
                        pos++;
                        /* bounded only allowed when rank == 1 */
                        if (bounded && rank > 1)
                        {
                            return(null);
                        }
                        /* n.b. bounded needs both modifiers: -2 == bounded, 1 == rank 1 array */
                        if (res.Modifiers == null)
                        {
                            res.Modifiers = new List <int> ();
                        }
                        if (bounded)
                        {
                            res.Modifiers.Add(-2);
                        }
                        res.Modifiers.Add(rank);
                    }
                    else
                    {
                        // Generic args
                        if (rank > 0 || isptr)
                        {
                            return(null);
                        }
                        isptr             = false;
                        res.TypeArguments = new List <ParsedName> ();
                        while (pos < name.Length)
                        {
                            while (pos < name.Length && name [pos] == ' ')
                            {
                                pos++;
                            }
                            bool fqname = false;
                            if (pos < name.Length && name [pos] == '[')
                            {
                                pos++;
                                fqname = true;
                            }

                            var arg = ParseName(name, true, pos, out pos);
                            if (arg == null)
                            {
                                return(null);
                            }
                            res.TypeArguments.Add(arg);

                            /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
                            if (fqname && pos < name.Length && name [pos] != ']')
                            {
                                if (name [pos] != ',')
                                {
                                    return(null);
                                }
                                pos++;
                                int aname_start = pos;
                                while (pos < name.Length && name [pos] != ']')
                                {
                                    pos++;
                                }
                                if (pos == name.Length)
                                {
                                    return(null);
                                }
                                while (Char.IsWhiteSpace(name [aname_start]))
                                {
                                    aname_start++;
                                }
                                if (aname_start == pos)
                                {
                                    return(null);
                                }
                                arg.AssemblyName = name.Substring(aname_start, pos - aname_start);
                                pos++;
                            }
                            else if (fqname && pos < name.Length && name [pos] == ']')
                            {
                                pos++;
                            }
                            if (pos < name.Length && name [pos] == ']')
                            {
                                pos++;
                                break;
                            }
                            else if (pos == name.Length)
                            {
                                return(null);
                            }
                            pos++;
                        }
                    }
                    break;

                case ']':
                    if (recursed)
                    {
                        end = true;
                        break;
                    }
                    return(null);

                case ',':
                    if (recursed)
                    {
                        end = true;
                        break;
                    }
                    pos++;
                    while (pos < name.Length && Char.IsWhiteSpace(name [pos]))
                    {
                        pos++;
                    }
                    if (pos == name.Length)
                    {
                        return(null);
                    }
                    res.AssemblyName = name.Substring(pos);
                    end = true;
                    break;

                default:
                    return(null);
                }
                if (end)
                {
                    break;
                }
            }

            end_pos = pos;
            return(res);
        }
コード例 #6
0
        private static string stripStyles(string s, NumberStyles style, NumberFormatInfo nfi,
                                          out int decPos, out bool isNegative, out bool expFlag, out int exp, bool throwex)
        {
            isNegative = false;
            expFlag    = false;
            exp        = 0;
            decPos     = -1;

            bool hasSign = false;
            bool hasOpeningParentheses     = false;
            bool hasDecimalPoint           = false;
            bool allowedLeadingWhiteSpace  = ((style & NumberStyles.AllowLeadingWhite) != 0);
            bool allowedTrailingWhiteSpace = ((style & NumberStyles.AllowTrailingWhite) != 0);
            bool allowedLeadingSign        = ((style & NumberStyles.AllowLeadingSign) != 0);
            bool allowedTrailingSign       = ((style & NumberStyles.AllowTrailingSign) != 0);
            bool allowedParentheses        = ((style & NumberStyles.AllowParentheses) != 0);
            bool allowedThousands          = ((style & NumberStyles.AllowThousands) != 0);
            bool allowedDecimalPoint       = ((style & NumberStyles.AllowDecimalPoint) != 0);
            bool allowedExponent           = ((style & NumberStyles.AllowExponent) != 0);

            /* get rid of currency symbol */
            bool hasCurrency = false;

            if ((style & NumberStyles.AllowCurrencySymbol) != 0)
            {
                int index = s.IndexOf(nfi.CurrencySymbol);
                if (index >= 0)
                {
                    s           = s.Remove(index, nfi.CurrencySymbol.Length);
                    hasCurrency = true;
                }
            }

            string decimalSep = (hasCurrency) ? nfi.CurrencyDecimalSeparator : nfi.NumberDecimalSeparator;
            string groupSep   = (hasCurrency) ? nfi.CurrencyGroupSeparator : nfi.NumberGroupSeparator;

            int pos = 0;
            int len = s.Length;

            StringBuilder sb = new StringBuilder(len);

            // leading
            while (pos < len)
            {
                char ch = s[pos];
                if (Char.IsDigit(ch))
                {
                    break; // end of leading
                }
                else if (allowedLeadingWhiteSpace && Char.IsWhiteSpace(ch))
                {
                    pos++;
                }
                else if (allowedParentheses && ch == '(' && !hasSign && !hasOpeningParentheses)
                {
                    hasOpeningParentheses = true;
                    hasSign    = true;
                    isNegative = true;
                    pos++;
                }
                else if (allowedLeadingSign && ch == nfi.NegativeSign[0] && !hasSign)
                {
                    int slen = nfi.NegativeSign.Length;
                    if (slen == 1 || s.IndexOf(nfi.NegativeSign, pos, slen) == pos)
                    {
                        hasSign    = true;
                        isNegative = true;
                        pos       += slen;
                    }
                }
                else if (allowedLeadingSign && ch == nfi.PositiveSign[0] && !hasSign)
                {
                    int slen = nfi.PositiveSign.Length;
                    if (slen == 1 || s.IndexOf(nfi.PositiveSign, pos, slen) == pos)
                    {
                        hasSign = true;
                        pos    += slen;
                    }
                }
                else if (allowedDecimalPoint && ch == decimalSep[0])
                {
                    int slen = decimalSep.Length;
                    if (slen != 1 && s.IndexOf(decimalSep, pos, slen) != pos)
                    {
                        if (throwex)
                        {
                            ThrowAtPos(pos);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    break;
                }
                else
                {
                    if (throwex)
                    {
                        ThrowAtPos(pos);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            if (pos == len)
            {
                if (throwex)
                {
                    throw new FormatException(Locale.GetText("No digits found"));
                }
                else
                {
                    return(null);
                }
            }

            // digits
            while (pos < len)
            {
                char ch = s[pos];
                if (Char.IsDigit(ch))
                {
                    sb.Append(ch);
                    pos++;
                }
                else if (allowedThousands && ch == groupSep[0])
                {
                    int slen = groupSep.Length;
                    if (slen != 1 && s.IndexOf(groupSep, pos, slen) != pos)
                    {
                        if (throwex)
                        {
                            ThrowAtPos(pos);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    pos += slen;
                }
                else if (allowedDecimalPoint && ch == decimalSep[0] && !hasDecimalPoint)
                {
                    int slen = decimalSep.Length;
                    if (slen == 1 || s.IndexOf(decimalSep, pos, slen) == pos)
                    {
                        decPos          = sb.Length;
                        hasDecimalPoint = true;
                        pos            += slen;
                    }
                }
                else
                {
                    break;
                }
            }

            // exponent
            if (pos < len)
            {
                char ch = s[pos];
                if (allowedExponent && Char.ToUpperInvariant(ch) == 'E')
                {
                    expFlag = true;
                    pos++;
                    if (pos >= len)
                    {
                        if (throwex)
                        {
                            ThrowInvalidExp();
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    ch = s[pos];
                    bool isNegativeExp = false;
                    if (ch == nfi.PositiveSign[0])
                    {
                        int slen = nfi.PositiveSign.Length;
                        if (slen == 1 || s.IndexOf(nfi.PositiveSign, pos, slen) == pos)
                        {
                            pos += slen;
                            if (pos >= len)
                            {
                                if (throwex)
                                {
                                    ThrowInvalidExp();
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                        }
                    }
                    else if (ch == nfi.NegativeSign[0])
                    {
                        int slen = nfi.NegativeSign.Length;
                        if (slen == 1 || s.IndexOf(nfi.NegativeSign, pos, slen) == pos)
                        {
                            pos += slen;
                            if (pos >= len)
                            {
                                if (throwex)
                                {
                                    ThrowInvalidExp();
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                            isNegativeExp = true;
                        }
                    }
                    ch = s[pos];
                    if (!Char.IsDigit(ch))
                    {
                        if (throwex)
                        {
                            ThrowInvalidExp();
                        }
                        else
                        {
                            return(null);
                        }
                    }

                    exp = ch - '0';
                    pos++;
                    while (pos < len && Char.IsDigit(s[pos]))
                    {
                        exp *= 10;
                        exp += s[pos] - '0';
                        pos++;
                    }
                    if (isNegativeExp)
                    {
                        exp *= -1;
                    }
                }
            }

            // trailing
            while (pos < len)
            {
                char ch = s[pos];
                if (allowedTrailingWhiteSpace && Char.IsWhiteSpace(ch))
                {
                    pos++;
                }
                else if (allowedParentheses && ch == ')' && hasOpeningParentheses)
                {
                    hasOpeningParentheses = false;
                    pos++;
                }
                else if (allowedTrailingSign && ch == nfi.NegativeSign[0] && !hasSign)
                {
                    int slen = nfi.NegativeSign.Length;
                    if (slen == 1 || s.IndexOf(nfi.NegativeSign, pos, slen) == pos)
                    {
                        hasSign    = true;
                        isNegative = true;
                        pos       += slen;
                    }
                }
                else if (allowedTrailingSign && ch == nfi.PositiveSign[0] && !hasSign)
                {
                    int slen = nfi.PositiveSign.Length;
                    if (slen == 1 || s.IndexOf(nfi.PositiveSign, pos, slen) == pos)
                    {
                        hasSign = true;
                        pos    += slen;
                    }
                }
                else
                {
                    if (throwex)
                    {
                        ThrowAtPos(pos);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            if (hasOpeningParentheses)
            {
                if (throwex)
                {
                    throw new FormatException(Locale.GetText("Closing Parentheses not found"));
                }
                else
                {
                    return(null);
                }
            }

            if (!hasDecimalPoint)
            {
                decPos = sb.Length;
            }

            return(sb.ToString());
        }
コード例 #7
0
        // FIXME: check if digits are group in correct numbers between the group separators
        internal static bool Parse(string s, NumberStyles style, IFormatProvider provider, bool tryParse, out double result, out Exception exc)
        {
            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }
            if (s.Length == 0)
            {
                if (!tryParse)
                {
                    exc = new FormatException();
                }
                return(false);
            }
            // yes it's counter intuitive (buggy?) but even TryParse actually throws in this case
            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                string msg = Locale.GetText("Double doesn't support parsing with '{0}'.", "AllowHexSpecifier");
                throw new ArgumentException(msg);
            }
            if (style > NumberStyles.Any)
            {
                if (!tryParse)
                {
                    exc = new ArgumentException();
                }
                return(false);
            }

            NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

            if (format == null)
            {
                throw new Exception("How did this happen?");
            }

            //
            // validate and prepare string for C
            //
            int  len  = s.Length;
            int  didx = 0;
            int  sidx = 0;
            char c;
            bool allow_leading_white  = (style & NumberStyles.AllowLeadingWhite) != 0;
            bool allow_trailing_white = ((style & NumberStyles.AllowTrailingWhite) != 0);

            if (allow_leading_white)
            {
                while (sidx < len && Char.IsWhiteSpace(s [sidx]))
                {
                    sidx++;
                }

                if (sidx == len)
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }
            }
            int sEndPos = s.Length - 1;

            if (allow_trailing_white)
            {
                while (Char.IsWhiteSpace(s [sEndPos]))
                {
                    sEndPos--;
                }
            }

            if (TryParseStringConstant(format.NaNSymbol, s, sidx, sEndPos))
            {
                result = double.NaN;
                return(true);
            }
            if (TryParseStringConstant(format.PositiveInfinitySymbol, s, sidx, sEndPos))
            {
                result = double.PositiveInfinity;
                return(true);
            }
            if (TryParseStringConstant(format.NegativeInfinitySymbol, s, sidx, sEndPos))
            {
                result = double.NegativeInfinity;
                return(true);
            }

            byte [] b = new byte [len + 1];

            //
            // Machine state
            //
            var state = ParseState.AllowSign;

            //
            // Setup
            //
            string decimal_separator     = null;
            string group_separator       = null;
            string currency_symbol       = null;
            int    decimal_separator_len = 0;
            int    group_separator_len   = 0;
            int    currency_symbol_len   = 0;

            if ((style & NumberStyles.AllowDecimalPoint) != 0)
            {
                decimal_separator     = format.NumberDecimalSeparator;
                decimal_separator_len = decimal_separator.Length;
            }
            if ((style & NumberStyles.AllowThousands) != 0)
            {
                group_separator     = format.NumberGroupSeparator;
                group_separator_len = group_separator.Length;
            }
            if ((style & NumberStyles.AllowCurrencySymbol) != 0)
            {
                currency_symbol     = format.CurrencySymbol;
                currency_symbol_len = currency_symbol.Length;
            }
            string positive = format.PositiveSign;
            string negative = format.NegativeSign;
            bool   allow_trailing_parenthes = false;

            for (; sidx < len; sidx++)
            {
                c = s [sidx];

                if (c == '\0')
                {
                    sidx = len;
                    continue;
                }

                switch (state)
                {
                case ParseState.AllowSign:
                    if ((style & NumberStyles.AllowLeadingSign) != 0)
                    {
                        if (c == positive [0] &&
                            s.Substring(sidx, positive.Length) == positive)
                        {
                            state = ParseState.Digits;
                            sidx += positive.Length - 1;
                            continue;
                        }

                        if (c == negative [0] &&
                            s.Substring(sidx, negative.Length) == negative)
                        {
                            state      = ParseState.Digits;
                            b [didx++] = (byte)'-';
                            sidx      += negative.Length - 1;
                            continue;
                        }
                    }

                    if ((style & NumberStyles.AllowParentheses) != 0 && c == '(')
                    {
                        b [didx++] = (byte)'-';
                        state      = ParseState.Digits;
                        allow_trailing_parenthes = true;
                        continue;
                    }

                    state = ParseState.Digits;
                    goto case ParseState.Digits;

                case ParseState.Digits:
                    if (Char.IsDigit(c))
                    {
                        b [didx++] = (byte)c;
                        break;
                    }

                    if (c == 'e' || c == 'E')
                    {
                        goto case ParseState.Decimal;
                    }

                    if (allow_trailing_parenthes && c == ')')
                    {
                        allow_trailing_parenthes = false;
                        state = ParseState.ConsumeWhiteSpace;
                        continue;
                    }

                    if (decimal_separator_len > 0 &&
                        decimal_separator [0] == c)
                    {
                        if (String.CompareOrdinal(s, sidx, decimal_separator, 0, decimal_separator_len) == 0)
                        {
                            b [didx++] = (byte)'.';
                            sidx      += decimal_separator_len - 1;
                            state      = ParseState.Decimal;
                            break;
                        }
                    }
                    if (group_separator_len > 0 &&
                        group_separator [0] == c)
                    {
                        if (s.Substring(sidx, group_separator_len) ==
                            group_separator)
                        {
                            sidx += group_separator_len - 1;
                            break;
                        }
                    }
                    if (currency_symbol_len > 0 &&
                        currency_symbol [0] == c)
                    {
                        if (s.Substring(sidx, currency_symbol_len) ==
                            currency_symbol)
                        {
                            sidx += currency_symbol_len - 1;
                            currency_symbol_len = 0;
                            break;
                        }
                    }

                    state = ParseState.TrailingSymbols;
                    goto case ParseState.TrailingSymbols;

                case ParseState.Decimal:
                    if (Char.IsDigit(c))
                    {
                        b [didx++] = (byte)c;
                        break;
                    }

                    if (c == 'e' || c == 'E')
                    {
                        if ((style & NumberStyles.AllowExponent) == 0)
                        {
                            if (!tryParse)
                            {
                                exc = new FormatException("Unknown char: " + c);
                            }
                            return(false);
                        }
                        b [didx++] = (byte)c;
                        state      = ParseState.ExponentSign;
                        break;
                    }

                    state = ParseState.TrailingSymbols;
                    goto case ParseState.TrailingSymbols;

                case ParseState.ExponentSign:
                    if (Char.IsDigit(c))
                    {
                        state = ParseState.Exponent;
                        goto case ParseState.Exponent;
                    }

                    if (c == positive [0] &&
                        s.Substring(sidx, positive.Length) == positive)
                    {
                        state = ParseState.Digits;
                        sidx += positive.Length - 1;
                        continue;
                    }

                    if (c == negative [0] &&
                        s.Substring(sidx, negative.Length) == negative)
                    {
                        state      = ParseState.Digits;
                        b [didx++] = (byte)'-';
                        sidx      += negative.Length - 1;
                        continue;
                    }

                    goto case ParseState.ConsumeWhiteSpace;

                case ParseState.Exponent:
                    if (Char.IsDigit(c))
                    {
                        b [didx++] = (byte)c;
                        break;
                    }

                    state = ParseState.TrailingSymbols;
                    goto case ParseState.TrailingSymbols;

                case ParseState.TrailingSymbols:
                    if ((style & NumberStyles.AllowTrailingSign) != 0)
                    {
                        if (positive != null && c == positive [0] &&
                            s.Substring(sidx, positive.Length) == positive)
                        {
                            state = ParseState.ConsumeWhiteSpace;
                            sidx += positive.Length - 1;
                            allow_trailing_parenthes = false;
                            positive = null;
                            continue;
                        }

                        if (negative != null && c == negative [0] &&
                            s.Substring(sidx, negative.Length) == negative)
                        {
                            state = ParseState.ConsumeWhiteSpace;
                            Array.Copy(b, 0, b, 1, didx);
                            b [0] = (byte)'-';
                            ++didx;
                            sidx += negative.Length - 1;
                            allow_trailing_parenthes = false;
                            negative = null;
                            continue;
                        }
                    }

                    if (currency_symbol_len > 0 &&
                        currency_symbol [0] == c)
                    {
                        if (s.Substring(sidx, currency_symbol_len) ==
                            currency_symbol)
                        {
                            sidx += currency_symbol_len - 1;
                            currency_symbol_len = 0;
                            break;
                        }
                    }

                    if (allow_trailing_white && Char.IsWhiteSpace(c))
                    {
                        break;
                    }

                    goto case ParseState.ConsumeWhiteSpace;

                case ParseState.ConsumeWhiteSpace:
                    if (allow_trailing_parenthes && c == ')')
                    {
                        allow_trailing_parenthes = false;
                        state = ParseState.ConsumeWhiteSpace;
                        break;
                    }

                    if (allow_trailing_white && Char.IsWhiteSpace(c))
                    {
                        state = ParseState.ConsumeWhiteSpace;
                        break;
                    }

                    if (!tryParse)
                    {
                        exc = new FormatException("Unknown char");
                    }
                    return(false);
                }

                if (state == ParseState.Exit)
                {
                    break;
                }
            }

            b [didx] = 0;
            unsafe
            {
                fixed(byte *p = &b[0])
                {
                    double retVal;

                    if (!ParseImpl(p, out retVal))
                    {
                        if (!tryParse)
                        {
                            exc = GetFormatException();
                        }
                        return(false);
                    }
                    if (IsPositiveInfinity(retVal) || IsNegativeInfinity(retVal))
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException();
                        }
                        return(false);
                    }

                    result = retVal;
                    return(true);
                }
            }
        }
コード例 #8
0
        internal static bool Parse(string s, bool tryParse, out short result, out Exception exc)
        {
            short val = 0;
            int   len;
            int   i, sign = 1;
            bool  digits_seen = false;

            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s [i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            c = s [i];
            if (c == '+')
            {
                i++;
            }
            else if (c == '-')
            {
                sign = -1;
                i++;
            }

            for (; i < len; i++)
            {
                c = s [i];
                if (c >= '0' && c <= '9')
                {
                    byte d = (byte)(c - '0');

                    if (val > (MaxValue / 10))
                    {
                        goto overflow;
                    }

                    if (val == (MaxValue / 10))
                    {
                        if ((d > (MaxValue % 10)) && (sign == 1 || (d > ((MaxValue % 10) + 1))))
                        {
                            goto overflow;
                        }
                        if (sign == -1)
                        {
                            val = (short)((val * sign * 10) - d);
                        }
                        else
                        {
                            val = (short)((val * 10) + d);
                        }

                        if (Int32.ProcessTrailingWhitespace(tryParse, s, i + 1, ref exc))
                        {
                            result = val;
                            return(true);
                        }
                        goto overflow;
                    }
                    else
                    {
                        val = (short)(val * 10 + d);
                    }


                    digits_seen = true;
                }
                else if (!Int32.ProcessTrailingWhitespace(tryParse, s, i, ref exc))
                {
                    return(false);
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            if (sign == -1)
            {
                result = (short)(val * sign);
            }
            else
            {
                result = val;
            }

            return(true);

overflow:
            if (!tryParse)
            {
                exc = new OverflowException("Value is too large");
            }
            return(false);
        }
コード例 #9
0
        internal static bool Parse(string s, bool tryParse, out uint result, out Exception exc)
        {
            uint val = 0;
            int  len;
            int  i;
            bool digits_seen       = false;
            bool has_negative_sign = false;

            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s[i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = IntParser.GetFormatException();
                }
                return(false);
            }

            if (s[i] == '+')
            {
                i++;
            }
            else
            if (s[i] == '-')
            {
                i++;
                has_negative_sign = true;
            }

            for (; i < len; i++)
            {
                c = s[i];

                if (c >= '0' && c <= '9')
                {
                    uint d = (uint)(c - '0');

                    ulong v = ((ulong)val) * 10 + d;
                    if (v > MaxValue)
                    {
                        if (!tryParse)
                        {
                            exc = IntParser.GetOverflowException();
                        }
                        return(false);
                    }
                    val         = (uint)v;
                    digits_seen = true;
                }
                else
                {
                    if (Char.IsWhiteSpace(c))
                    {
                        for (i++; i < len; i++)
                        {
                            if (!Char.IsWhiteSpace(s[i]))
                            {
                                if (!tryParse)
                                {
                                    exc = IntParser.GetFormatException();
                                }
                                return(false);
                            }
                        }
                        break;
                    }
                    else
                    {
                        if (!tryParse)
                        {
                            exc = IntParser.GetFormatException();
                        }
                        return(false);
                    }
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = IntParser.GetFormatException();
                }
                return(false);
            }

            // -0 is legal but other negative values are not
            if (has_negative_sign && (val > 0))
            {
                if (!tryParse)
                {
                    exc = new OverflowException(
                        Locale.GetText("Negative number"));
                }
                return(false);
            }

            result = val;
            return(true);
        }
コード例 #10
0
        internal static bool Parse(string s, bool tryParse, out long result, out Exception exc)
        {
            long val = 0;
            int  len;
            int  i;
            int  sign        = 1;
            bool digits_seen = false;

            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s[i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            c = s[i];
            if (c == '+')
            {
                i++;
            }
            else if (c == '-')
            {
                sign = -1;
                i++;
            }

            for (; i < len; i++)
            {
                c = s[i];

                if (c >= '0' && c <= '9')
                {
                    if (tryParse)
                    {
                        val = val * 10 + (c - '0') * sign;

                        if (sign == 1)
                        {
                            if (val < 0)
                            {
                                return(false);
                            }
                        }
                        else if (val > 0)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        val = checked (val * 10 + (c - '0') * sign);
                    }
                    digits_seen = true;
                }
                else
                {
                    if (Char.IsWhiteSpace(c))
                    {
                        for (i++; i < len; i++)
                        {
                            if (!Char.IsWhiteSpace(s[i]))
                            {
                                if (!tryParse)
                                {
                                    exc = Int32.GetFormatException();
                                }
                                return(false);
                            }
                        }
                        break;
                    }
                    else
                    {
                        if (!tryParse)
                        {
                            exc = Int32.GetFormatException();
                        }
                        return(false);
                    }
                }
            }
            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            result = val;
            return(true);
        }
コード例 #11
0
        internal static bool Parse(string s, bool tryParse, out ulong result, out Exception exc)
        {
            ulong val = 0;
            int   len;
            int   i;
            bool  digits_seen       = false;
            bool  has_negative_sign = false;

            exc    = null;
            result = 0;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = new ArgumentNullException("s");
                }
                return(false);
            }

            len = s.Length;

            char c;

            for (i = 0; i < len; i++)
            {
                c = s [i];
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            if (i == len)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            if (s [i] == '+')
            {
                i++;
            }
            else if (s [i] == '-')
            {
                i++;
                has_negative_sign = true;
            }

            // Actual number stuff
            for (; i < len; i++)
            {
                c = s [i];

                if (c >= '0' && c <= '9')
                {
                    uint d = (uint)(c - '0');

                    if (val > MaxValue / 10 || (val == MaxValue / 10 && d > MaxValue % 10))
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException("Value is too large.");
                        }
                        return(false);
                    }

                    val         = (val * 10) + d;
                    digits_seen = true;
                }
                else if (!Int32.ProcessTrailingWhitespace(tryParse, s, i, ref exc))
                {
                    return(false);
                }
            }

            if (!digits_seen)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            if (has_negative_sign && val > 0)
            {
                if (!tryParse)
                {
                    exc = new OverflowException("Negative number.");
                }
                return(false);
            }

            result = val;
            return(true);
        }