public static long ParseInt64(ReadOnlySpan <char> value)
        {
            if (value.IsEmpty)
            {
                throw new FormatException(MemoryProvider.BadFormat);
            }

            long result   = 0;
            int  i        = 0;
            int  end      = value.Length;
            var  state    = ParseState.LeadingWhite;
            bool negative = false;

            //skip leading whitespaces
            while (i < end && JsonUtils.IsWhiteSpace(value[i]))
            {
                i++;
            }

            if (i == end)
            {
                throw new FormatException(MemoryProvider.BadFormat);
            }

            //skip leading zeros
            while (i < end && value[i] == '0')
            {
                state = ParseState.Number;
                i++;
            }

            while (i < end)
            {
                var c = value[i++];

                switch (state)
                {
                case ParseState.LeadingWhite:
                    if (c == '-')
                    {
                        negative = true;
                        state    = ParseState.Sign;
                    }
                    else if (c == '0')
                    {
                        state = ParseState.TrailingWhite;
                    }
                    else if (c > '0' && c <= '9')
                    {
                        result = -(c - '0');
                        state  = ParseState.Number;
                    }
                    else
                    {
                        throw new FormatException(MemoryProvider.BadFormat);
                    }

                    break;

                case ParseState.Sign:
                    if (c == '0')
                    {
                        state = ParseState.TrailingWhite;
                    }
                    else if (c > '0' && c <= '9')
                    {
                        result = -(c - '0');
                        state  = ParseState.Number;
                    }
                    else
                    {
                        throw new FormatException(MemoryProvider.BadFormat);
                    }

                    break;

                case ParseState.Number:
                    if (c >= '0' && c <= '9')
                    {
                        checked
                        {
                            result = 10 * result - (c - '0');
                        }

                        if (result < minValue
                            ) //check only minvalue, because in absolute value it's greater than maxvalue
                        {
                            throw DefaultMemory.CreateOverflowException(maxValue);
                        }
                    }
                    else if (JsonUtils.IsWhiteSpace(c))
                    {
                        state = ParseState.TrailingWhite;
                    }
                    else
                    {
                        throw new FormatException(MemoryProvider.BadFormat);
                    }

                    break;

                case ParseState.TrailingWhite:
                    if (JsonUtils.IsWhiteSpace(c))
                    {
                        state = ParseState.TrailingWhite;
                    }
                    else
                    {
                        throw new FormatException(MemoryProvider.BadFormat);
                    }

                    break;
                }
            }

            if (state != ParseState.Number && state != ParseState.TrailingWhite)
            {
                throw new FormatException(MemoryProvider.BadFormat);
            }

            if (negative)
            {
                return(result);
            }

            checked
            {
                result = -result;
            }

            if (result > maxValue)
            {
                throw DefaultMemory.CreateOverflowException(maxValue);
            }

            return(result);
        }
Beispiel #2
0
        internal static ulong ParseUInt64(ReadOnlySpan<char> value)
        {
            if (value.IsEmpty)
                throw new FormatException(MemoryProvider.BadFormat);

            ulong result = 0;
            int i = 0;
            int end = value.Length;
            var state = ParseState.LeadingWhite;

            //skip leading whitespaces
            while (i < end && JsonUtils.IsWhiteSpace(value[i])) i++;

            if (i == end)
                throw new FormatException(MemoryProvider.BadFormat);

            //skip leading zeros
            while (i < end && value[i] == '0')
            {
                state = ParseState.Number;
                i++;
            }

            while (i < end)
            {
                var c = value[i++];

                switch (state)
                {
                    case ParseState.LeadingWhite:
                        if (JsonUtils.IsWhiteSpace(c))
                            break;
                        if (c == '0')
                        {
                            state = ParseState.TrailingWhite;
                        }
                        else if (c > '0' && c <= '9')
                        {
                            result = (ulong) (c - '0');
                            state = ParseState.Number;
                        }
                        else throw new FormatException(MemoryProvider.BadFormat);


                        break;
                    case ParseState.Number:
                        if (c >= '0' && c <= '9')
                        {
                            checked
                            {
                                result = 10 * result + (ulong) (c - '0');
                            }

                            if (result > maxValue
                            ) //check only minvalue, because in absolute value it's greater than maxvalue
                                throw DefaultMemory.CreateOverflowException(maxValue);
                        }
                        else if (JsonUtils.IsWhiteSpace(c))
                        {
                            state = ParseState.TrailingWhite;
                        }
                        else throw new FormatException(MemoryProvider.BadFormat);

                        break;
                    case ParseState.TrailingWhite:
                        if (JsonUtils.IsWhiteSpace(c))
                        {
                            state = ParseState.TrailingWhite;
                        }
                        else throw new FormatException(MemoryProvider.BadFormat);

                        break;
                }
            }

            if (state != ParseState.Number && state != ParseState.TrailingWhite)
                throw new FormatException(MemoryProvider.BadFormat);

            return result;
        }