/// <summary>
        /// Breaks apart an event key into the individual and normalized key and
        /// any modifiers.
        /// </summary>
        /// <param name="evt">The evt.</param>
        /// <param name="key">The key.</param>
        /// <param name="modifiers">The mod.</param>
        public static void DecomposeKeys(
            EventKey evt,
            out Key key,
            out ModifierType modifiers)
        {
            // Use the keymap to decompose various elements of the hardware keys.
            uint keyval;
            int  effectiveGroup,
                 level;
            ModifierType consumedModifiers;

            keymap.TranslateKeyboardState(
                evt.HardwareKeycode,
                evt.State,
                evt.Group,
                out keyval,
                out effectiveGroup,
                out level,
                out consumedModifiers);

            // Break out the identified keys and modifiers.
            key       = (Key)keyval;
            modifiers = evt.State & ~consumedModifiers;

            // Normalize some of the keys that don't make sense.
            if (key == Key.ISO_Left_Tab)
            {
                key        = Key.Tab;
                modifiers |= ModifierType.ShiftMask;
            }

            // Check to see if we are a character and pull out the shift key if
            // it is a capital letter. This is used to normalize so all the
            // keys are uppercase with a shift modifier.
            bool shiftWasConsumed = ((evt.State ^ modifiers) & ModifierType.ShiftMask)
                                    != 0;
            var unicode = (char)Keyval.ToUnicode((uint)key);

            if (shiftWasConsumed && Char.IsUpper(unicode))
            {
                modifiers |= ModifierType.ShiftMask;
            }

            if (Char.IsLetter(unicode) &&
                Char.IsLower(unicode))
            {
                key = (Key)Char.ToUpper(unicode);
            }
        }
Example #2
0
        internal static bool Parse(string s, NumberStyles style, IFormatProvider fp, bool tryParse, out int 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 = GetFormatException();
                }
                return(false);
            }

            NumberFormatInfo nfi = null;

            if (fp != null)
            {
                Type typeNFI = typeof(System.Globalization.NumberFormatInfo);
                nfi = (NumberFormatInfo)fp.GetFormat(typeNFI);
            }
            if (nfi == null)
            {
                nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
            }

            if (!CheckStyle(style, tryParse, ref exc))
            {
                return(false);
            }

            bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
            bool AllowHexSpecifier   = (style & NumberStyles.AllowHexSpecifier) != 0;
            bool AllowThousands      = (style & NumberStyles.AllowThousands) != 0;
            bool AllowDecimalPoint   = (style & NumberStyles.AllowDecimalPoint) != 0;
            bool AllowParentheses    = (style & NumberStyles.AllowParentheses) != 0;
            bool AllowTrailingSign   = (style & NumberStyles.AllowTrailingSign) != 0;
            bool AllowLeadingSign    = (style & NumberStyles.AllowLeadingSign) != 0;
            bool AllowTrailingWhite  = (style & NumberStyles.AllowTrailingWhite) != 0;
            bool AllowLeadingWhite   = (style & NumberStyles.AllowLeadingWhite) != 0;
            bool AllowExponent       = (style & NumberStyles.AllowExponent) != 0;

            int pos = 0;

            if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
            {
                return(false);
            }

            bool foundOpenParentheses = false;
            bool negative             = false;
            bool foundSign            = false;
            bool foundCurrency        = false;

            // Pre-number stuff
            if (AllowParentheses && s [pos] == '(')
            {
                foundOpenParentheses = true;
                foundSign            = true;
                negative             = true;     // MS always make the number negative when there parentheses
                                                 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
                pos++;
                if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                {
                    return(false);
                }

                if (s.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }

                if (s.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }
            }

            if (AllowLeadingSign && !foundSign)
            {
                // Sign + Currency
                FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        FindCurrency(ref pos, s, nfi,
                                     ref foundCurrency);
                        if (foundCurrency && AllowLeadingWhite &&
                            !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (foundCurrency)
                    {
                        if (!foundSign && AllowLeadingSign)
                        {
                            FindSign(ref pos, s, nfi, ref foundSign,
                                     ref negative);
                            if (foundSign && AllowLeadingWhite &&
                                !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            int  number          = 0;
            int  nDigits         = 0;
            int  decimalPointPos = -1;
            int  digitValue;
            char hexDigit;

            // Number stuff
            while (pos < s.Length)
            {
                if (!ValidDigit(s [pos], AllowHexSpecifier))
                {
                    if (AllowThousands &&
                        (FindOther(ref pos, s, nfi.NumberGroupSeparator) ||
                         FindOther(ref pos, s, nfi.CurrencyGroupSeparator)))
                    {
                        continue;
                    }

                    if (AllowDecimalPoint && decimalPointPos < 0 &&
                        (FindOther(ref pos, s, nfi.NumberDecimalSeparator) ||
                         FindOther(ref pos, s, nfi.CurrencyDecimalSeparator)))
                    {
                        decimalPointPos = nDigits;
                        continue;
                    }

                    break;
                }

                nDigits++;

                if (AllowHexSpecifier)
                {
                    hexDigit = s [pos++];
                    if (Char.IsDigit(hexDigit))
                    {
                        digitValue = (int)(hexDigit - '0');
                    }
                    else if (Char.IsLower(hexDigit))
                    {
                        digitValue = (int)(hexDigit - 'a' + 10);
                    }
                    else
                    {
                        digitValue = (int)(hexDigit - 'A' + 10);
                    }

                    uint unumber = (uint)number;
                    if (tryParse)
                    {
                        if ((unumber & 0xf0000000) != 0)
                        {
                            return(false);
                        }

                        number = (int)(unumber * 16u + (uint)digitValue);
                    }
                    else
                    {
                        number = (int)checked (unumber * 16u + (uint)digitValue);
                    }

                    continue;
                }

                try {
                    // Calculations done as negative
                    // (abs (MinValue) > abs (MaxValue))
                    number = checked (number * 10 - (int)(s [pos++] - '0'));
                } catch (OverflowException) {
                    if (!tryParse)
                    {
                        exc = new OverflowException("Value too large or too small.");
                    }
                    return(false);
                }
            }

            // Post number stuff
            if (nDigits == 0)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            int exponent = 0;

            if (AllowExponent)
            {
                if (FindExponent(ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
                {
                    return(false);
                }
            }

            if (AllowTrailingSign && !foundSign)
            {
                // Sign + Currency
                FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign && pos < s.Length)
                {
                    if (AllowTrailingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }

                // Currency + sign
                FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency && pos < s.Length)
                {
                    if (AllowTrailingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (!foundSign && AllowTrailingSign)
                    {
                        FindSign(ref pos, s, nfi, ref foundSign,
                                 ref negative);
                    }
                }
            }

            if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite(ref pos, s, false, tryParse, ref exc))
            {
                return(false);
            }

            if (foundOpenParentheses)
            {
                if (pos >= s.Length || s [pos++] != ')')
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }
                if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }
            }

            if (pos < s.Length && s [pos] != '\u0000')
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            if (!negative && !AllowHexSpecifier)
            {
                if (tryParse)
                {
                    long lval = -((long)number);

                    if (lval < MinValue || lval > MaxValue)
                    {
                        return(false);
                    }
                    number = (int)lval;
                }
                else
                {
                    number = checked (-number);
                }
            }

            if (decimalPointPos >= 0)
            {
                exponent = exponent - nDigits + decimalPointPos;
            }

            if (exponent < 0)
            {
                //
                // Any non-zero values after decimal point are not allowed
                //
                int remainder;
                number = Math.DivRem(number, (int)Math.Pow(10, -exponent), out remainder);
                if (remainder != 0)
                {
                    if (!tryParse)
                    {
                        exc = new OverflowException("Value too large or too small.");
                    }
                    return(false);
                }
            }
            else if (exponent > 0)
            {
                //
                // result *= 10^exponent
                //
                // Reduce the risk of throwing an overflow exc
                //
                double res = checked (Math.Pow(10, exponent) * number);
                if (res < MinValue || res > MaxValue)
                {
                    if (!tryParse)
                    {
                        exc = new OverflowException("Value too large or too small.");
                    }
                    return(false);
                }

                number = (int)res;
            }

            result = number;
            return(true);
        }
Example #3
0
        internal static bool Parse(string s, NumberStyles style, IFormatProvider provider, bool tryParse, out uint 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 = Int32.GetFormatException();
                }
                return(false);
            }

            NumberFormatInfo nfi = null;

            if (provider != null)
            {
                Type typeNFI = typeof(NumberFormatInfo);
                nfi = (NumberFormatInfo)provider.GetFormat(typeNFI);
            }
            if (nfi == null)
            {
                nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
            }

            if (!Int32.CheckStyle(style, tryParse, ref exc))
            {
                return(false);
            }

            bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
            bool AllowHexSpecifier   = (style & NumberStyles.AllowHexSpecifier) != 0;
            bool AllowThousands      = (style & NumberStyles.AllowThousands) != 0;
            bool AllowDecimalPoint   = (style & NumberStyles.AllowDecimalPoint) != 0;
            bool AllowParentheses    = (style & NumberStyles.AllowParentheses) != 0;
            bool AllowTrailingSign   = (style & NumberStyles.AllowTrailingSign) != 0;
            bool AllowLeadingSign    = (style & NumberStyles.AllowLeadingSign) != 0;
            bool AllowTrailingWhite  = (style & NumberStyles.AllowTrailingWhite) != 0;
            bool AllowLeadingWhite   = (style & NumberStyles.AllowLeadingWhite) != 0;
            bool AllowExponent       = (style & NumberStyles.AllowExponent) != 0;

            int pos = 0;

            if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
            {
                return(false);
            }

            bool foundOpenParentheses = false;
            bool negative             = false;
            bool foundSign            = false;
            bool foundCurrency        = false;

            // Pre-number stuff
            if (AllowParentheses && s [pos] == '(')
            {
                foundOpenParentheses = true;
                foundSign            = true;
                negative             = true;     // MS always make the number negative when there parentheses
                                                 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
                pos++;
                if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                {
                    return(false);
                }

                if (s.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
                {
                    if (!tryParse)
                    {
                        exc = Int32.GetFormatException();
                    }
                    return(false);
                }

                if (s.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
                {
                    if (!tryParse)
                    {
                        exc = Int32.GetFormatException();
                    }
                    return(false);
                }
            }

            if (AllowLeadingSign && !foundSign)
            {
                // Sign + Currency
                Int32.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        Int32.FindCurrency(ref pos, s, nfi,
                                           ref foundCurrency);
                        if (foundCurrency && AllowLeadingWhite &&
                            !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                Int32.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (foundCurrency)
                    {
                        if (!foundSign && AllowLeadingSign)
                        {
                            Int32.FindSign(ref pos, s, nfi, ref foundSign,
                                           ref negative);
                            if (foundSign && AllowLeadingWhite &&
                                !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            uint number          = 0;
            int  nDigits         = 0;
            int  decimalPointPos = -1;
            uint digitValue;
            char hexDigit;

            // Number stuff
            // Just the same as Int32, but this one adds instead of substract
            do
            {
                if (!Int32.ValidDigit(s [pos], AllowHexSpecifier))
                {
                    if (AllowThousands &&
                        (Int32.FindOther(ref pos, s, nfi.NumberGroupSeparator) ||
                         Int32.FindOther(ref pos, s, nfi.CurrencyGroupSeparator)))
                    {
                        continue;
                    }

                    if (AllowDecimalPoint && decimalPointPos < 0 &&
                        (Int32.FindOther(ref pos, s, nfi.NumberDecimalSeparator) ||
                         Int32.FindOther(ref pos, s, nfi.CurrencyDecimalSeparator)))
                    {
                        decimalPointPos = nDigits;
                        continue;
                    }

                    break;
                }

                nDigits++;

                if (AllowHexSpecifier)
                {
                    hexDigit = s [pos++];
                    if (Char.IsDigit(hexDigit))
                    {
                        digitValue = (uint)(hexDigit - '0');
                    }
                    else if (Char.IsLower(hexDigit))
                    {
                        digitValue = (uint)(hexDigit - 'a' + 10);
                    }
                    else
                    {
                        digitValue = (uint)(hexDigit - 'A' + 10);
                    }

                    if (tryParse)
                    {
                        ulong l = number * 16 + digitValue;

                        if (l > MaxValue)
                        {
                            return(false);
                        }
                        number = (uint)l;
                    }
                    else
                    {
                        number = checked (number * 16 + digitValue);
                    }

                    continue;
                }

                try {
                    number = checked (number * 10 + (uint)(s [pos++] - '0'));
                } catch (OverflowException) {
                    if (!tryParse)
                    {
                        exc = new OverflowException(Locale.GetText("Value too large or too small."));
                    }
                    return(false);
                }
            } while (pos < s.Length);

            // Post number stuff
            if (nDigits == 0)
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

            int exponent = 0;

            if (AllowExponent)
            {
                if (Int32.FindExponent(ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
                {
                    return(false);
                }
            }

            if (AllowTrailingSign && !foundSign)
            {
                // Sign + Currency
                Int32.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign && pos < s.Length)
                {
                    if (AllowTrailingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }

                // Currency + sign
                Int32.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency && pos < s.Length)
                {
                    if (AllowTrailingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (!foundSign && AllowTrailingSign)
                    {
                        Int32.FindSign(ref pos, s, nfi, ref foundSign,
                                       ref negative);
                    }
                }
            }

            if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
            {
                return(false);
            }

            if (foundOpenParentheses)
            {
                if (pos >= s.Length || s [pos++] != ')')
                {
                    if (!tryParse)
                    {
                        exc = Int32.GetFormatException();
                    }
                    return(false);
                }
                if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }
            }

            if (pos < s.Length && s [pos] != '\u0000')
            {
                if (!tryParse)
                {
                    exc = Int32.GetFormatException();
                }
                return(false);
            }

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

            if (decimalPointPos >= 0)
            {
                exponent = exponent - nDigits + decimalPointPos;
            }

            if (exponent < 0)
            {
                //
                // Any non-zero values after decimal point are not allowed
                //
                long remainder;
                number = (uint)Math.DivRem(number, (int)Math.Pow(10, -exponent), out remainder);
                if (remainder != 0)
                {
                    if (!tryParse)
                    {
                        exc = new OverflowException("Value too large or too small.");
                    }
                    return(false);
                }
            }
            else if (exponent > 0)
            {
                //
                // result *= 10^exponent
                //
                // Reduce the risk of throwing an overflow exc
                //
                double res = checked (Math.Pow(10, exponent) * number);
                if (res < MinValue || res > MaxValue)
                {
                    if (!tryParse)
                    {
                        exc = new OverflowException("Value too large or too small.");
                    }
                    return(false);
                }

                number = (uint)res;
            }

            result = number;
            return(true);
        }
Example #4
0
 /// <summary>
 /// Indicates whether the specified Unicode character is categorized as a lowercase letter.
 /// </summary>
 /// <param name="Char">The Unicode character to evaluate.</param>
 /// <returns>true if <paramref name="Char"/> is a lowercase letter; otherwise, false.</returns>
 public static Boolean IsLower(this Char Char) => Char.IsLower(Char);
Example #5
0
        internal static bool Parse(string s, NumberStyles style, IFormatProvider fp, bool tryParse, out int result, out Exception exc)
        {
            result = 0;
            exc    = null;

            if (s == null)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

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

            if (s.Length == 0)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            NumberFormatInfo nfi;

            if (fp != null)
            {
                Type typeNFI = typeof(System.Globalization.NumberFormatInfo);
                nfi = (NumberFormatInfo)fp.GetFormat(typeNFI);
            }
            else
            {
                nfi = CultureInfo.CurrentCulture.NumberFormat;
            }
            if (!CheckStyle(style, tryParse, ref exc))
            {
                return(false);
            }
            bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
            bool AllowHexSpecifier   = (style & NumberStyles.AllowHexSpecifier) != 0;
            bool AllowThousands      = (style & NumberStyles.AllowThousands) != 0;
            bool AllowDecimalPoint   = (style & NumberStyles.AllowDecimalPoint) != 0;
            bool AllowParentheses    = (style & NumberStyles.AllowParentheses) != 0;
            bool AllowTrailingSign   = (style & NumberStyles.AllowTrailingSign) != 0;
            bool AllowLeadingSign    = (style & NumberStyles.AllowLeadingSign) != 0;
            bool AllowTrailingWhite  = (style & NumberStyles.AllowTrailingWhite) != 0;
            bool AllowLeadingWhite   = (style & NumberStyles.AllowLeadingWhite) != 0;
            bool AllowExponent       = (style & NumberStyles.AllowExponent) != 0;

            int pos = 0;

            if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
            {
                return(false);
            }

            bool foundOpenParentheses = false;
            bool negative             = false;
            bool foundSign            = false;
            bool foundCurrency        = false;

            // Pre-number stuff
            if (AllowParentheses && s[pos] == '(')
            {
                foundOpenParentheses = true;
                foundSign            = true;
                negative             = true; // MS always make the number negative when there parentheses
                // even when NumberFormatInfo.NumberNegativePattern != 0!!!
                pos++;
                if (AllowLeadingWhite && !!JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                {
                    return(false);
                }
                if (s.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }

                if (s.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }
            }

            if (AllowLeadingSign && !foundSign)
            {
                // Sign + Currency
                FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        FindCurrency(ref pos, s, nfi, ref foundCurrency);
                        if (foundCurrency && AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (foundCurrency)
                    {
                        if (!foundSign && AllowLeadingSign)
                        {
                            FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                            if (foundSign && AllowLeadingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            int  number            = 0;
            int  nDigits           = 0;
            bool decimalPointFound = false;
            int  digitValue;
            char hexDigit;

            // Number stuff
            do
            {
                if (!ValidDigit(s[pos], AllowHexSpecifier))
                {
                    if (AllowThousands && FindOther(ref pos, s, nfi.NumberGroupSeparator))
                    {
                        continue;
                    }
                    else
                    {
                        if (!decimalPointFound && AllowDecimalPoint && FindOther(ref pos, s, nfi.NumberDecimalSeparator))
                        {
                            decimalPointFound = true;
                            continue;
                        }
                    }
                    break;
                }
                else if (AllowHexSpecifier)
                {
                    nDigits++;
                    hexDigit = s[pos++];
                    if (Char.IsDigit(hexDigit))
                    {
                        digitValue = (int)(hexDigit - '0');
                    }
                    else if (Char.IsLower(hexDigit))
                    {
                        digitValue = (int)(hexDigit - 'a' + 10);
                    }
                    else
                    {
                        digitValue = (int)(hexDigit - 'A' + 10);
                    }
                    uint unumber = (uint)number;
                    try
                    {
                        number = (int)checked (unumber * 16u + (uint)digitValue);
                    }
                    catch (OverflowException e)
                    {
                        exc = e;
                        return(false);
                    }
                }
                else if (decimalPointFound)
                {
                    nDigits++;
                    // Allows decimal point as long as it's only
                    // followed by zeroes.
                    if (s[pos++] != '0')
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException("Value too large or too small.");
                        }
                        return(false);
                    }
                }
                else
                {
                    nDigits++;

                    try
                    {
                        // Calculations done as negative
                        // (abs (MinValue) > abs (MaxValue))
                        number = checked (
                            number * 10 -
                            (int)(s[pos++] - '0')
                            );
                    }
                    catch (OverflowException)
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException("Value too large or too small.");
                        }
                        return(false);
                    }
                }
            } while (pos < s.Length);

            // Post number stuff
            if (nDigits == 0)
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            if (AllowExponent)
            {
                FindExponent(ref pos, s);
            }
            if (AllowTrailingSign && !foundSign)
            {
                // Sign + Currency
                FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowTrailingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        FindCurrency(ref pos, s, nfi, ref foundCurrency);
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowTrailingWhite && !JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (!foundSign && AllowTrailingSign)
                    {
                        FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                    }
                }
            }

            if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite(ref pos, s, false, tryParse, ref exc))
            {
                return(false);
            }

            if (foundOpenParentheses)
            {
                if (pos >= s.Length || s[pos++] != ')')
                {
                    if (!tryParse)
                    {
                        exc = GetFormatException();
                    }
                    return(false);
                }
                if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }
            }

            if (pos < s.Length && s[pos] != '\u0000')
            {
                if (!tryParse)
                {
                    exc = GetFormatException();
                }
                return(false);
            }

            if (!negative && !AllowHexSpecifier)
            {
                number = checked (-number);
            }

            result = number;

            return(true);
        }
Example #6
0
        internal static bool Parse(string s, NumberStyles style, IFormatProvider fp, bool tryParse, out long 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("Input string was not " +
                                              "in the correct format: s.Length==0.");
                }
                return(false);
            }

            NumberFormatInfo nfi;

            if (fp != null)
            {
                Type typeNFI = typeof(System.Globalization.NumberFormatInfo);
                nfi = (NumberFormatInfo)fp.GetFormat(typeNFI);
            }
            else
            {
                nfi = CultureInfo.CurrentCulture.NumberFormat;
            }

            if (!Int32.CheckStyle(style, tryParse, ref exc))
            {
                return(false);
            }

            bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
            bool AllowHexSpecifier   = (style & NumberStyles.AllowHexSpecifier) != 0;
            bool AllowThousands      = (style & NumberStyles.AllowThousands) != 0;
            bool AllowDecimalPoint   = (style & NumberStyles.AllowDecimalPoint) != 0;
            bool AllowParentheses    = (style & NumberStyles.AllowParentheses) != 0;
            bool AllowTrailingSign   = (style & NumberStyles.AllowTrailingSign) != 0;
            bool AllowLeadingSign    = (style & NumberStyles.AllowLeadingSign) != 0;
            bool AllowTrailingWhite  = (style & NumberStyles.AllowTrailingWhite) != 0;
            bool AllowLeadingWhite   = (style & NumberStyles.AllowLeadingWhite) != 0;

            int pos = 0;

            if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
            {
                return(false);
            }

            bool foundOpenParentheses = false;
            bool negative             = false;
            bool foundSign            = false;
            bool foundCurrency        = false;

            // Pre-number stuff
            if (AllowParentheses && s[pos] == '(')
            {
                foundOpenParentheses = true;
                foundSign            = true;
                negative             = true; // MS always make the number negative when there parentheses
                // even when NumberFormatInfo.NumberNegativePattern != 0!!!
                pos++;
                if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                {
                    return(false);
                }

                if (s.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
                {
                    if (!tryParse)
                    {
                        exc = new FormatException("Input string was not in the correct " +
                                                  "format: Has Negative Sign.");
                    }
                    return(false);
                }
                if (s.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
                {
                    if (!tryParse)
                    {
                        exc = new FormatException("Input string was not in the correct " +
                                                  "format: Has Positive Sign.");
                    }
                    return(false);
                }
            }

            if (AllowLeadingSign && !foundSign)
            {
                // Sign + Currency
                Int32.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        Int32.FindCurrency(ref pos, s, nfi,
                                           ref foundCurrency);
                        if (foundCurrency && AllowLeadingWhite &&
                            !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                Int32.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowLeadingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (foundCurrency)
                    {
                        if (!foundSign && AllowLeadingSign)
                        {
                            Int32.FindSign(ref pos, s, nfi, ref foundSign,
                                           ref negative);
                            if (foundSign && AllowLeadingWhite &&
                                !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            long number            = 0;
            int  nDigits           = 0;
            bool decimalPointFound = false;
            int  digitValue;
            char hexDigit;

            // Number stuff
            do
            {
                if (!Int32.ValidDigit(s[pos], AllowHexSpecifier))
                {
                    if (AllowThousands &&
                        (Int32.FindOther(ref pos, s, nfi.NumberGroupSeparator) ||
                         Int32.FindOther(ref pos, s, nfi.CurrencyGroupSeparator)))
                    {
                        continue;
                    }
                    else
                    if (!decimalPointFound && AllowDecimalPoint &&
                        (Int32.FindOther(ref pos, s, nfi.NumberDecimalSeparator) ||
                         Int32.FindOther(ref pos, s, nfi.CurrencyDecimalSeparator)))
                    {
                        decimalPointFound = true;
                        continue;
                    }

                    break;
                }
                else if (AllowHexSpecifier)
                {
                    nDigits++;
                    hexDigit = s[pos++];
                    if (Char.IsDigit(hexDigit))
                    {
                        digitValue = (int)(hexDigit - '0');
                    }
                    else if (Char.IsLower(hexDigit))
                    {
                        digitValue = (int)(hexDigit - 'a' + 10);
                    }
                    else
                    {
                        digitValue = (int)(hexDigit - 'A' + 10);
                    }

                    ulong unumber = (ulong)number;

                    // IMPROVME: We could avoid catching OverflowException
                    try
                    {
                        number = (long)checked (unumber * 16ul + (ulong)digitValue);
                    }
                    catch (OverflowException e)
                    {
                        if (!tryParse)
                        {
                            exc = e;
                        }
                        return(false);
                    }
                }
                else if (decimalPointFound)
                {
                    nDigits++;
                    // Allows decimal point as long as it's only
                    // followed by zeroes.
                    if (s[pos++] != '0')
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException("Value too large or too " +
                                                        "small.");
                        }
                        return(false);
                    }
                }
                else
                {
                    nDigits++;

                    try
                    {
                        // Calculations done as negative
                        // (abs (MinValue) > abs (MaxValue))
                        number = checked (
                            number * 10 -
                            (long)(s[pos++] - '0')
                            );
                    }
                    catch (OverflowException)
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException("Value too large or too " +
                                                        "small.");
                        }
                        return(false);
                    }
                }
            } while (pos < s.Length);

            // Post number stuff
            if (nDigits == 0)
            {
                if (!tryParse)
                {
                    exc = new FormatException("Input string was not in the correct format: nDigits == 0.");
                }
                return(false);
            }

            if (AllowTrailingSign && !foundSign)
            {
                // Sign + Currency
                Int32.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowTrailingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        Int32.FindCurrency(ref pos, s, nfi,
                                           ref foundCurrency);
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                if (nfi.CurrencyPositivePattern == 3 && s[pos++] != ' ')
                {
                    if (tryParse)
                    {
                        return(false);
                    }
                    else
                    {
                        throw new FormatException("Input string was not in the correct format: no space between number and currency symbol.");
                    }
                }

                Int32.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency && pos < s.Length)
                {
                    if (AllowTrailingWhite && !Int32.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (!foundSign && AllowTrailingSign)
                    {
                        Int32.FindSign(ref pos, s, nfi, ref foundSign,
                                       ref negative);
                    }
                }
            }

            if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
            {
                return(false);
            }

            if (foundOpenParentheses)
            {
                if (pos >= s.Length || s[pos++] != ')')
                {
                    if (!tryParse)
                    {
                        exc = new FormatException("Input string was not in the correct " +
                                                  "format: No room for close parens.");
                    }
                    return(false);
                }
                if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }
            }

            if (pos < s.Length && s[pos] != '\u0000')
            {
                if (!tryParse)
                {
                    exc = new FormatException("Input string was not in the correct format: Did not parse entire string. pos = "
                                              + pos + " s.Length = " + s.Length);
                }
                return(false);
            }


            if (!negative && !AllowHexSpecifier)
            {
                try
                {
                    number = checked (-number);
                }
                catch (OverflowException e)
                {
                    if (!tryParse)
                    {
                        exc = e;
                    }
                    return(false);
                }
            }

            result = number;
            return(true);
        }
Example #7
0
        /// <summary>
        /// Spacifies a string value by adding a separator (usually space) between words
        /// </summary>
        /// <param name="value">The string value to spacify</param>
        /// <param name="separator">The separator value to use, default is a space</param>
        /// <returns>The spacified string value</returns>
        public static string Spacify(this string value, string separator = " ")
        {
            if (String.IsNullOrEmpty(value) || value.Contains(separator))
            {
                return(value);
            }
            else
            {
                var result       = String.Empty;
                var previousChar = '\0';

                foreach (var currentChar in value)
                {
                    if (previousChar != Char.MinValue && Char.IsLetter(currentChar))
                    {
                        if ((Char.IsNumber(previousChar) && !Char.IsNumber(currentChar)) || (Char.IsUpper(currentChar) && Char.IsLower(previousChar)))
                        {
                            result += separator + Convert.ToString(currentChar);
                        }
                        else
                        {
                            result += Convert.ToString(currentChar);
                        }
                    }
                    else
                    {
                        result += Convert.ToString(currentChar);
                    }

                    previousChar = currentChar;
                }

                if (false == String.IsNullOrEmpty(result))
                {
                    result = result.Replace("_", separator).Replace("  ", " ");
                }

                return(result);
            }
        }
        internal static bool Parse(string s, NumberStyles style, IFormatProvider provider, bool tryParse, out uint 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 = ParseHelper.GetFormatException();
                }
                return(false);
            }

            NumberFormatInfo nfi = null;

            if (provider != null)
            {
                Type typeNFI = typeof(NumberFormatInfo);
                nfi = (NumberFormatInfo)provider.GetFormat(typeNFI);
            }
            if (nfi == null)
            {
                nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
            }

            if (!ParseHelper.CheckStyle(style, tryParse, ref exc))
            {
                return(false);
            }

            bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
            bool AllowHexSpecifier   = (style & NumberStyles.AllowHexSpecifier) != 0;
            bool AllowThousands      = (style & NumberStyles.AllowThousands) != 0;
            bool AllowDecimalPoint   = (style & NumberStyles.AllowDecimalPoint) != 0;
            bool AllowParentheses    = (style & NumberStyles.AllowParentheses) != 0;
            bool AllowTrailingSign   = (style & NumberStyles.AllowTrailingSign) != 0;
            bool AllowLeadingSign    = (style & NumberStyles.AllowLeadingSign) != 0;
            bool AllowTrailingWhite  = (style & NumberStyles.AllowTrailingWhite) != 0;
            bool AllowLeadingWhite   = (style & NumberStyles.AllowLeadingWhite) != 0;

            int pos = 0;

            if (AllowLeadingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
            {
                return(false);
            }

            bool foundOpenParentheses = false;
            bool negative             = false;
            bool foundSign            = false;
            bool foundCurrency        = false;

            // Pre-number stuff
            if (AllowParentheses && s[pos] == '(')
            {
                foundOpenParentheses = true;
                foundSign            = true;
                negative             = true; // MS always make the number negative when there parentheses
                // even when NumberFormatInfo.NumberNegativePattern != 0!!!
                pos++;
                if (AllowLeadingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                {
                    return(false);
                }

                if (s.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
                {
                    if (!tryParse)
                    {
                        exc = ParseHelper.GetFormatException();
                    }
                    return(false);
                }
                if (s.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
                {
                    if (!tryParse)
                    {
                        exc = ParseHelper.GetFormatException();
                    }
                    return(false);
                }
            }

            if (AllowLeadingSign && !foundSign)
            {
                // Sign + Currency
                ParseHelper.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowLeadingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        ParseHelper.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                        if (foundCurrency && AllowLeadingWhite &&
                            !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                ParseHelper.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowLeadingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (foundCurrency)
                    {
                        if (!foundSign && AllowLeadingSign)
                        {
                            ParseHelper.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                            if (foundSign && AllowLeadingWhite &&
                                !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            uint number            = 0;
            int  nDigits           = 0;
            bool decimalPointFound = false;
            uint digitValue;
            char hexDigit;

            // Number stuff
            // Just the same as Int32, but this one adds instead of substract
            do
            {
                if (!ParseHelper.ValidDigit(s[pos], AllowHexSpecifier))
                {
                    if (AllowThousands && ParseHelper.FindOther(ref pos, s, nfi.NumberGroupSeparator))
                    {
                        continue;
                    }
                    else
                    if (!decimalPointFound && AllowDecimalPoint &&
                        ParseHelper.FindOther(ref pos, s, nfi.NumberDecimalSeparator))
                    {
                        decimalPointFound = true;
                        continue;
                    }
                    break;
                }
                else if (AllowHexSpecifier)
                {
                    nDigits++;
                    hexDigit = s[pos++];
                    if (Char.IsDigit(hexDigit))
                    {
                        digitValue = (uint)(hexDigit - '0');
                    }
                    else if (Char.IsLower(hexDigit))
                    {
                        digitValue = (uint)(hexDigit - 'a' + 10);
                    }
                    else
                    {
                        digitValue = (uint)(hexDigit - 'A' + 10);
                    }

                    if (tryParse)
                    {
                        ulong l = number * 16 + digitValue;

                        if (l > MaxValue)
                        {
                            return(false);
                        }
                        number = (uint)l;
                    }
                    else
                    {
                        number = checked (number * 16 + digitValue);
                    }
                }
                else if (decimalPointFound)
                {
                    nDigits++;
                    // Allows decimal point as long as it's only
                    // followed by zeroes.
                    if (s[pos++] != '0')
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException(String.Format("Value too large or too small."));
                        }
                        return(false);
                    }
                }
                else
                {
                    nDigits++;

                    try
                    {
                        number = checked (number * 10 + (uint)(s[pos++] - '0'));
                    }
                    catch (OverflowException)
                    {
                        if (!tryParse)
                        {
                            exc = new OverflowException(String.Format("Value too large or too small."));
                        }
                        return(false);
                    }
                }
            } while (pos < s.Length);

            // Post number stuff
            if (nDigits == 0)
            {
                if (!tryParse)
                {
                    exc = ParseHelper.GetFormatException();
                }
                return(false);
            }

            if (AllowTrailingSign && !foundSign)
            {
                // Sign + Currency
                ParseHelper.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                if (foundSign)
                {
                    if (AllowTrailingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (AllowCurrencySymbol)
                    {
                        ParseHelper.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                    }
                }
            }

            if (AllowCurrencySymbol && !foundCurrency)
            {
                // Currency + sign
                ParseHelper.FindCurrency(ref pos, s, nfi, ref foundCurrency);
                if (foundCurrency)
                {
                    if (AllowTrailingWhite && !ParseHelper.JumpOverWhite(ref pos, s, true, tryParse, ref exc))
                    {
                        return(false);
                    }
                    if (!foundSign && AllowTrailingSign)
                    {
                        ParseHelper.FindSign(ref pos, s, nfi, ref foundSign, ref negative);
                    }
                }
            }

            if (AllowTrailingWhite && pos < s.Length && !ParseHelper.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
            {
                return(false);
            }

            if (foundOpenParentheses)
            {
                if (pos >= s.Length || s[pos++] != ')')
                {
                    if (!tryParse)
                    {
                        exc = ParseHelper.GetFormatException();
                    }
                    return(false);
                }
                if (AllowTrailingWhite && pos < s.Length && !ParseHelper.JumpOverWhite(ref pos, s, false, tryParse, ref exc))
                {
                    return(false);
                }
            }

            if (pos < s.Length && s[pos] != '\u0000')
            {
                if (!tryParse)
                {
                    exc = ParseHelper.GetFormatException();
                }
                return(false);
            }

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

            result = number;

            return(true);
        }