private static void ParseDecimal()

in csharp/src/Drivers/Apache/Hive2/DecimalUtility.cs [247:458]


        private static void ParseDecimal(ReadOnlySpan<byte> value, out ParserState parserState)
        {
            ParserState state = new();
            int index = 0;
            int length = value.Length;
            while (index < length)
            {
                byte c = value[index];
                switch (state.CurrentState)
                {
                    case ParseState.StartWhiteSpace:
                        if (c != AsciiSpace)
                        {
                            state.CurrentState = ParseState.SignOrDigitOrDecimal;
                        }
                        else
                        {
                            index++;
                        }
                        break;
                    case ParseState.SignOrDigitOrDecimal:
                        // Is Ascii Numeric
                        if ((uint)(c - AsciiZero) <= AsciiDigitMaxIndex)
                        {
                            if (!state.HasZero && c == AsciiZero) state.HasZero |= true;
                            state.IntegerStart = index;
                            state.IntegerEnd = index;
                            index++;
                            state.CurrentState = ParseState.DigitOrDecimalOrExponent;
                        }
                        else if (c == AsciiMinus || c == AsciiPlus)
                        {
                            state.SignIndex = index;
                            index++;
                            state.CurrentState = ParseState.DigitOrDecimalOrExponent;
                        }
                        else if (c == AsciiPeriod)
                        {
                            state.DecimalIndex = index;
                            index++;
                            state.CurrentState = ParseState.FractionOrExponent;
                        }
                        else if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.DigitOrDecimalOrExponent:
                        // Is Ascii Numeric
                        if ((uint)(c - AsciiZero) <= AsciiDigitMaxIndex)
                        {
                            if (state.IntegerStart == -1) state.IntegerStart = index;
                            if (!state.HasZero && c == AsciiZero) state.HasZero |= true;
                            state.IntegerEnd = index;
                            index++;
                        }
                        else if (c == AsciiPeriod)
                        {
                            state.DecimalIndex = index;
                            index++;
                            state.CurrentState = ParseState.FractionOrExponent;
                        }
                        else if (c == AsciiUpperE || c == AsciiLowerE)
                        {
                            state.ExponentIndex = index;
                            index++;
                            state.CurrentState = ParseState.ExpSignOrExpValue;
                        }
                        else if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.FractionOrExponent:
                        // Is Ascii Numeric
                        if ((uint)(c - AsciiZero) <= AsciiDigitMaxIndex)
                        {
                            if (state.FractionalStart == -1) state.FractionalStart = index;
                            if (!state.HasZero && c == AsciiZero) state.HasZero |= true;
                            state.FractionalEnd = index;
                            index++;
                        }
                        else if (c == AsciiUpperE || c == AsciiLowerE)
                        {
                            state.ExponentIndex = index;
                            index++;
                            state.CurrentState = ParseState.ExpSignOrExpValue;
                        }
                        else if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.ExpSignOrExpValue:
                        // Is Ascii Numeric
                        if ((uint)(c - AsciiZero) <= AsciiDigitMaxIndex)
                        {
                            if (state.ExponentStart == -1) state.ExponentStart = index;
                            state.ExponentEnd = index;
                            index++;
                            state.CurrentState = ParseState.ExpValue;
                        }
                        else if (c == AsciiMinus || c == AsciiPlus)
                        {
                            state.ExpSignIndex = index;
                            index++;
                            state.CurrentState = ParseState.ExpValue;
                        }
                        else if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.ExpValue:
                        // Is Ascii Numeric
                        if ((uint)(c - AsciiZero) <= AsciiDigitMaxIndex)
                        {
                            if (state.ExponentStart == -1) state.ExponentStart = index;
                            state.ExponentEnd = index;
                            index++;
                        }
                        else if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.EndWhiteSpace:
                        if (c == AsciiSpace)
                        {
                            index++;
                            state.CurrentState = ParseState.EndWhiteSpace;
                        }
                        else
                        {
                            state.CurrentState = ParseState.Invalid;
                        }
                        break;
                    case ParseState.Invalid:
                        throw new ArgumentOutOfRangeException(nameof(value), Encoding.UTF8.GetString(value), $"Invalid numeric value at index {index}.");
                }
            }
            // Trim leading zeros from integer portion
            if (state.IntegerStart != -1 && state.IntegerEnd != -1)
            {
                for (int i = state.IntegerStart; i <= state.IntegerEnd; i++)
                {
                    if (value[i] != AsciiZero) break;

                    state.IntegerStart = i + 1;
                    if (state.IntegerStart > state.IntegerEnd)
                    {
                        state.IntegerStart = -1;
                        state.IntegerEnd = -1;
                        break;
                    }
                }
            }
            // Trim trailing zeros from fractional portion
            if (state.FractionalStart != -1 && state.FractionalEnd != -1)
            {
                for (int i = state.FractionalEnd; i >= state.FractionalStart; i--)
                {
                    if (value[i] != AsciiZero) break;

                    state.FractionalEnd = i - 1;
                    if (state.FractionalStart > state.FractionalEnd)
                    {
                        state.FractionalStart = -1;
                        state.FractionalEnd = -1;
                        break;
                    }
                }
            }
            // Must have a integer or fractional part.
            if (state.IntegerStart == -1 && state.FractionalStart == -1)
            {
                if (!state.HasZero)
                    throw new ArgumentOutOfRangeException(nameof(value), Encoding.UTF8.GetString(value), "input does not contain a valid numeric value.");
                else
                {
                    state.IntegerStart = value.IndexOf(AsciiZero);
                    state.IntegerEnd = state.IntegerStart;
                }
            }

            parserState = state;
        }