private object ReadNumericLiteral()
{
var sb = new StringBuilder();
if (PeekChar() == '-')
{
sb.Append((char)ReadChar());
}
int c;
int x = 0;
bool zeroStart = PeekChar() == '0';
for (; ; x++)
{
c = PeekChar();
if (c < '0' || '9' < c)
{
break;
}
sb.Append((char)ReadChar());
if (zeroStart && x == 1)
{
throw JsonError(SR.ArgumentException_LeadingZeros);
}
}
if (x == 0) // Reached e.g. for "- "
{
throw JsonError(SR.ArgumentException_NoDigitFound);
}
// fraction
bool hasFrac = false;
int fdigits = 0;
if (PeekChar() == '.')
{
hasFrac = true;
sb.Append((char)ReadChar());
if (PeekChar() < 0)
{
throw JsonError(SR.ArgumentException_ExtraDot);
}
while (true)
{
c = PeekChar();
if (c < '0' || '9' < c)
{
break;
}
sb.Append((char)ReadChar());
fdigits++;
}
if (fdigits == 0)
{
throw JsonError(SR.ArgumentException_ExtraDot);
}
}
c = PeekChar();
if (c != 'e' && c != 'E')
{
if (!hasFrac)
{
int valueInt;
if (int.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out valueInt))
{
return valueInt;
}
long valueLong;
if (long.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out valueLong))
{
return valueLong;
}
ulong valueUlong;
if (ulong.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out valueUlong))
{
return valueUlong;
}
}
decimal valueDecimal;
if (decimal.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out valueDecimal) && valueDecimal != 0)
{
return valueDecimal;
}
}
else
{
// exponent
sb.Append((char)ReadChar());
if (PeekChar() < 0)
{
throw JsonError(SR.ArgumentException_IncompleteExponent);
}
c = PeekChar();
if (c == '-')
{
sb.Append((char)ReadChar());
}
else if (c == '+')
{
sb.Append((char)ReadChar());
}
if (PeekChar() < 0)
{
throw JsonError(SR.ArgumentException_IncompleteExponent);
}
while (true)
{
c = PeekChar();
if (c < '0' || '9' < c)
{
break;
}
sb.Append((char)ReadChar());
}
}
return double.Parse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture);
}