private void ParseReadNumber()

in src/Elastic.Apm/Libraries/Newtonsoft.Json/JsonTextReader.cs [1810:2067]


		private void ParseReadNumber(ReadType readType, char firstChar, int initialPosition)
		{
			MiscellaneousUtils.Assert(CharBuffer != null);

			// set state to PostValue now so that if there is an error parsing the number then the reader can continue
			SetPostValueState(true);

			_stringReference = new StringReference(CharBuffer, initialPosition, CharPos - initialPosition);

			object numberValue;
			JsonToken numberType;

			var singleDigit = char.IsDigit(firstChar) && _stringReference.Length == 1;
			var nonBase10 = firstChar == '0' && _stringReference.Length > 1 && _stringReference.Chars[_stringReference.StartIndex + 1] != '.'
				&& _stringReference.Chars[_stringReference.StartIndex + 1] != 'e' && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E';

			switch (readType)
			{
				case ReadType.ReadAsString:
				{
					var number = _stringReference.ToString();

					// validate that the string is a valid number
					if (nonBase10)
					{
						try
						{
							if (number.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
								Convert.ToInt64(number, 16);
							else
								Convert.ToInt64(number, 8);
						}
						catch (Exception ex)
						{
							throw ThrowReaderError("Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}
					}
					else
					{
						if (!double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out _))
							throw ThrowReaderError("Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture,
								_stringReference.ToString()));
					}

					numberType = JsonToken.String;
					numberValue = number;
				}
					break;
				case ReadType.ReadAsInt32:
				{
					if (singleDigit)
					{
						// digit char values start at 48
						numberValue = firstChar - 48;
					}
					else if (nonBase10)
					{
						var number = _stringReference.ToString();

						try
						{
							var integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
								? Convert.ToInt32(number, 16)
								: Convert.ToInt32(number, 8);

							numberValue = integer;
						}
						catch (Exception ex)
						{
							throw ThrowReaderError("Input string '{0}' is not a valid integer.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}
					}
					else
					{
						var parseResult = ConvertUtils.Int32TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length,
							out var value);
						if (parseResult == ParseResult.Success)
							numberValue = value;
						else if (parseResult == ParseResult.Overflow)
							throw ThrowReaderError(
								"JSON integer {0} is too large or small for an Int32.".FormatWith(CultureInfo.InvariantCulture,
									_stringReference.ToString()));
						else
							throw ThrowReaderError("Input string '{0}' is not a valid integer.".FormatWith(CultureInfo.InvariantCulture,
								_stringReference.ToString()));
					}

					numberType = JsonToken.Integer;
				}
					break;
				case ReadType.ReadAsDecimal:
				{
					if (singleDigit)
					{
						// digit char values start at 48
						numberValue = (decimal)firstChar - 48;
					}
					else if (nonBase10)
					{
						var number = _stringReference.ToString();

						try
						{
							// decimal.Parse doesn't support parsing hexadecimal values
							var integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
								? Convert.ToInt64(number, 16)
								: Convert.ToInt64(number, 8);

							numberValue = Convert.ToDecimal(integer);
						}
						catch (Exception ex)
						{
							throw ThrowReaderError("Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}
					}
					else
					{
						var parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length,
							out var value);
						if (parseResult == ParseResult.Success)
							numberValue = value;
						else
							throw ThrowReaderError("Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture,
								_stringReference.ToString()));
					}

					numberType = JsonToken.Float;
				}
					break;
				case ReadType.ReadAsDouble:
				{
					if (singleDigit)
					{
						// digit char values start at 48
						numberValue = (double)firstChar - 48;
					}
					else if (nonBase10)
					{
						var number = _stringReference.ToString();

						try
						{
							// double.Parse doesn't support parsing hexadecimal values
							var integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
								? Convert.ToInt64(number, 16)
								: Convert.ToInt64(number, 8);

							numberValue = Convert.ToDouble(integer);
						}
						catch (Exception ex)
						{
							throw ThrowReaderError("Input string '{0}' is not a valid double.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}
					}
					else
					{
						var number = _stringReference.ToString();

						if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
							numberValue = value;
						else
							throw ThrowReaderError("Input string '{0}' is not a valid double.".FormatWith(CultureInfo.InvariantCulture,
								_stringReference.ToString()));
					}

					numberType = JsonToken.Float;
				}
					break;
				case ReadType.Read:
				case ReadType.ReadAsInt64:
				{
					if (singleDigit)
					{
						// digit char values start at 48
						numberValue = (long)firstChar - 48;
						numberType = JsonToken.Integer;
					}
					else if (nonBase10)
					{
						var number = _stringReference.ToString();

						try
						{
							numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
								? Convert.ToInt64(number, 16)
								: Convert.ToInt64(number, 8);
						}
						catch (Exception ex)
						{
							throw ThrowReaderError("Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}

						numberType = JsonToken.Integer;
					}
					else
					{
						var parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length,
							out var value);
						if (parseResult == ParseResult.Success)
						{
							numberValue = value;
							numberType = JsonToken.Integer;
						}
						else if (parseResult == ParseResult.Overflow)
						{
#if HAVE_BIG_INTEGER
                                string number = _stringReference.ToString();

                                if (number.Length > MaximumJavascriptIntegerCharacterLength)
                                {
                                    throw ThrowReaderError("JSON integer {0} is too large to parse.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                                }

                                numberValue = BigIntegerParse(number, CultureInfo.InvariantCulture);
                                numberType = JsonToken.Integer;
#else
							throw ThrowReaderError(
								"JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture,
									_stringReference.ToString()));
#endif
						}
						else
						{
							if (_floatParseHandling == FloatParseHandling.Decimal)
							{
								parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex,
									_stringReference.Length, out var d);
								if (parseResult == ParseResult.Success)
									numberValue = d;
								else
									throw ThrowReaderError("Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture,
										_stringReference.ToString()));
							}
							else
							{
								var number = _stringReference.ToString();

								if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out var d))
									numberValue = d;
								else
									throw ThrowReaderError("Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture,
										_stringReference.ToString()));
							}

							numberType = JsonToken.Float;
						}
					}
				}
					break;
				default:
					throw JsonReaderException.Create(this, "Cannot read number value as type.");
			}

			ClearRecentString();

			// index has already been updated
			SetToken(numberType, numberValue, false);
		}