Esempio n. 1
0
        public static bool TryParse(byte[] text, int index, EncodingData encoding, Format.Parsed numericFormat,
                                    out ulong value, out int bytesConsumed)
        {
            // Precondition replacement
            if (text.Length < 1 || index < 0 || index >= text.Length)
            {
                value         = default(ulong);
                bytesConsumed = 0;
                return(false);
            }

            value         = default(ulong);
            bytesConsumed = 0;

            if (encoding.IsInvariantUtf8)
            {
                for (int byteIndex = index; byteIndex < text.Length; byteIndex++) // loop through the byte array
                {
                    byte nextByteVal = (byte)(text[byteIndex] - '0');
                    if (nextByteVal > 9) // if nextByteVal > 9, we know it is not a digit because any value less than '0' will overflow
                    // to greater than 9 since byte is an unsigned type.
                    {
                        if (bytesConsumed == 0) // check to see if we've processed any digits at all
                        {
                            return(false);
                        }
                        else
                        {
                            return(true); // otherwise return true
                        }
                    }
                    else if (value > UInt64.MaxValue / 10)
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }
                    // This next check uses a hardcoded 6 because the max values for unsigned types all end in 5s.
                    else if (value == UInt64.MaxValue / 10 && nextByteVal >= 6)  // overflow
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }

                    value = (ulong)(value * 10 + nextByteVal); // left shift the value and add the nextByte
                    bytesConsumed++;
                }
                return(true);
            }
            else if (encoding.IsInvariantUtf16)
            {
                for (int byteIndex = index; byteIndex < text.Length - 1; byteIndex += 2) // loop through the byte array two bytes at a time for UTF-16
                {
                    byte byteAfterNext = text[byteIndex + 1];
                    byte nextByteVal   = (byte)(text[byteIndex] - '0');
                    if (nextByteVal > 9 || byteAfterNext != 0)  // if the second byte isn't zero, this isn't an ASCII-equivalent code unit and we can quit here
                    // if nextByteVal > 9, we know it is not a digit because any value less than '0' will overflow
                    // to greater than 9 since byte is an unsigned type.
                    {
                        if (bytesConsumed == 0) // check to see if we've processed any digits at all
                        {
                            return(false);
                        }
                        else
                        {
                            return(true); // otherwise return true
                        }
                    }
                    else if (value > UInt64.MaxValue / 10)
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }
                    // This next check uses a hardcoded 6 because the max values for unsigned types all end in 5s.
                    else if (value == UInt64.MaxValue / 10 && nextByteVal >= 6)  // overflow
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }

                    value          = (ulong)(value * 10 + nextByteVal); // left shift the value and add the nextByte
                    bytesConsumed += 2;
                }
                return(true);
            }
            else
            {
                int byteIndex = index;
                while (byteIndex < text.Length)
                {
                    uint result;
                    int  oldIndex = byteIndex;
                    bool success  = encoding.TryParseNextCodingUnit(ref text, ref byteIndex, out result);

                    if (!success || result > 9)
                    {
                        if (bytesConsumed == 0) // check to see if we've processed any digits at all
                        {
                            return(false);
                        }
                        else
                        {
                            return(true); // otherwise return true
                        }
                    }
                    else if (value > UInt64.MaxValue / 10)
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }
                    // This next check uses a hardcoded 6 because the max values for unsigned types all end in 5s.
                    else if (value == UInt64.MaxValue / 10 && result >= 6) // overflow
                    {
                        value         = default(ulong);
                        bytesConsumed = 0;
                        return(false);
                    }

                    value          = (ulong)(value * 10 + result); // left shift the value and add the nextByte
                    bytesConsumed += byteIndex - oldIndex;
                }

                return(true);
            }
        }