예제 #1
0
        private void ClearRecentString()
        {
            if (_buffer != null)
                _buffer.Position = 0;

            _stringReference = new StringReference();
        }
예제 #2
0
        private void ParseUnquotedProperty()
        {
            int initialPosition = _charPos;

            // parse unquoted property name until whitespace or colon
            while (true)
            {
                switch (_chars[_charPos])
                {
                    case '\0':
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                                throw JsonReaderException.Create(this, "Unexpected end while parsing unquoted property name.");

                            break;
                        }

                        _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                        return;
                    default:
                        char currentChar = _chars[_charPos];

                        if (ValidIdentifierChar(currentChar))
                        {
                            _charPos++;
                            break;
                        }
                        else if (char.IsWhiteSpace(currentChar) || currentChar == ':')
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            return;
                        }

                        throw JsonReaderException.Create(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
                }
            }
        }
예제 #3
0
        private void ParseComment()
        {
            // should have already parsed / character before reaching this method
            _charPos++;

            if (!EnsureChars(1, false))
                throw JsonReaderException.Create(this, "Unexpected end while parsing comment.");

            bool singlelineComment;

            if (_chars[_charPos] == '*')
                singlelineComment = false;
            else if (_chars[_charPos] == '/')
                singlelineComment = true;
            else
                throw JsonReaderException.Create(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));

            _charPos++;

            int initialPosition = _charPos;

            bool commentFinished = false;

            while (!commentFinished)
            {
                switch (_chars[_charPos])
                {
                    case '\0':
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                            {
                                if (!singlelineComment)
                                    throw JsonReaderException.Create(this, "Unexpected end while parsing comment.");

                                _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                                commentFinished = true;
                            }
                        }
                        else
                        {
                            _charPos++;
                        }
                        break;
                    case '*':
                        _charPos++;

                        if (!singlelineComment)
                        {
                            if (EnsureChars(0, true))
                            {
                                if (_chars[_charPos] == '/')
                                {
                                    _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1);

                                    _charPos++;
                                    commentFinished = true;
                                }
                            }
                        }
                        break;
                    case StringUtils.CarriageReturn:
                        if (singlelineComment)
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            commentFinished = true;
                        }
                        ProcessCarriageReturn(true);
                        break;
                    case StringUtils.LineFeed:
                        if (singlelineComment)
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            commentFinished = true;
                        }
                        ProcessLineFeed();
                        break;
                    default:
                        _charPos++;
                        break;
                }
            }

            SetToken(JsonToken.Comment, _stringReference.ToString());

            ClearRecentString();
        }
예제 #4
0
        private void ReadStringIntoBuffer(char quote)
        {
            int charPos = _charPos;
            int initialPosition = _charPos;
            int lastWritePosition = _charPos;
            StringBuffer buffer = null;

            while (true)
            {
                switch (_chars[charPos++])
                {
                    case '\0':
                        if (_charsUsed == charPos - 1)
                        {
                            charPos--;

                            if (ReadData(true) == 0)
                            {
                                _charPos = charPos;
                                throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
                            }
                        }
                        break;
                    case '\\':
                        _charPos = charPos;
                        if (!EnsureChars(0, true))
                        {
                            _charPos = charPos;
                            throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
                        }

                        // start of escape sequence
                        int escapeStartPos = charPos - 1;

                        char currentChar = _chars[charPos];

                        char writeChar;

                        switch (currentChar)
                        {
                            case 'b':
                                charPos++;
                                writeChar = '\b';
                                break;
                            case 't':
                                charPos++;
                                writeChar = '\t';
                                break;
                            case 'n':
                                charPos++;
                                writeChar = '\n';
                                break;
                            case 'f':
                                charPos++;
                                writeChar = '\f';
                                break;
                            case 'r':
                                charPos++;
                                writeChar = '\r';
                                break;
                            case '\\':
                                charPos++;
                                writeChar = '\\';
                                break;
                            case '"':
                            case '\'':
                            case '/':
                                writeChar = currentChar;
                                charPos++;
                                break;
                            case 'u':
                                charPos++;
                                _charPos = charPos;
                                writeChar = ParseUnicode();

                                if (StringUtils.IsLowSurrogate(writeChar))
                                {
                                    // low surrogate with no preceding high surrogate; this char is replaced
                                    writeChar = UnicodeReplacementChar;
                                }
                                else if (StringUtils.IsHighSurrogate(writeChar))
                                {
                                    bool anotherHighSurrogate;

                                    // loop for handling situations where there are multiple consecutive high surrogates
                                    do
                                    {
                                        anotherHighSurrogate = false;

                                        // potential start of a surrogate pair
                                        if (EnsureChars(2, true) && _chars[_charPos] == '\\' && _chars[_charPos + 1] == 'u')
                                        {
                                            char highSurrogate = writeChar;

                                            _charPos += 2;
                                            writeChar = ParseUnicode();

                                            if (StringUtils.IsLowSurrogate(writeChar))
                                            {
                                                // a valid surrogate pair!
                                            }
                                            else if (StringUtils.IsHighSurrogate(writeChar))
                                            {
                                                // another high surrogate; replace current and start check over
                                                highSurrogate = UnicodeReplacementChar;
                                                anotherHighSurrogate = true;
                                            }
                                            else
                                            {
                                                // high surrogate not followed by low surrogate; original char is replaced
                                                highSurrogate = UnicodeReplacementChar;
                                            }

                                            if (buffer == null)
                                                buffer = GetBuffer();

                                            WriteCharToBuffer(buffer, highSurrogate, lastWritePosition, escapeStartPos);
                                            lastWritePosition = _charPos;
                                        }
                                        else
                                        {
                                            // there are not enough remaining chars for the low surrogate or is not follow by unicode sequence
                                            // replace high surrogate and continue on as usual
                                            writeChar = UnicodeReplacementChar;
                                        }
                                    } while (anotherHighSurrogate);
                                }

                                charPos = _charPos;
                                break;
                            default:
                                charPos++;
                                _charPos = charPos;
                                throw JsonReaderException.Create(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar));
                        }

                        if (buffer == null)
                            buffer = GetBuffer();

                        WriteCharToBuffer(buffer, writeChar, lastWritePosition, escapeStartPos);

                        lastWritePosition = charPos;
                        break;
                    case StringUtils.CarriageReturn:
                        _charPos = charPos - 1;
                        ProcessCarriageReturn(true);
                        charPos = _charPos;
                        break;
                    case StringUtils.LineFeed:
                        _charPos = charPos - 1;
                        ProcessLineFeed();
                        charPos = _charPos;
                        break;
                    case '"':
                    case '\'':
                        if (_chars[charPos - 1] == quote)
                        {
                            charPos--;

                            if (initialPosition == lastWritePosition)
                            {
                                _stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition);
                            }
                            else
                            {
                                if (buffer == null)
                                    buffer = GetBuffer();

                                if (charPos > lastWritePosition)
                                    buffer.Append(_chars, lastWritePosition, charPos - lastWritePosition);

                                _stringReference = new StringReference(buffer.GetInternalBuffer(), 0, buffer.Position);
                            }

                            charPos++;
                            _charPos = charPos;
                            return;
                        }
                        break;
                }
            }
        }
예제 #5
0
        private void ParseNumber()
        {
            ShiftBufferIfNeeded();

            char firstChar = _chars[_charPos];
            int initialPosition = _charPos;

            ReadNumberIntoBuffer();

            // 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(_chars, initialPosition, _charPos - initialPosition);

            object numberValue;
            JsonToken numberType;

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

	        if (_readType == ReadType.ReadAsInt32)
	        {
		        if (singleDigit)
		        {
			        // digit char values start at 48
			        numberValue = firstChar - 48;
		        }
		        else if (nonBase10)
		        {
			        string number = _stringReference.ToString();

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

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

		        numberType = JsonToken.Integer;
	        }
	        else
	        {
				const NumberStyles numberStyles = NumberStyles.Number | NumberStyles.AllowExponent; 
				if (_readType == ReadType.ReadAsDecimal)
		        {
			        if (singleDigit)
			        {
				        // digit char values start at 48
				        numberValue = (decimal) firstChar - 48;
			        }
			        else if (nonBase10)
			        {
				        string number = _stringReference.ToString();

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

					        numberValue = Convert.ToDecimal(integer);
				        }
				        catch (Exception ex)
				        {
					        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, number), ex);
				        }
			        }
			        else
			        {
				        string number = _stringReference.ToString();

				        decimal value;
						if (decimal.TryParse(number, numberStyles, CultureInfo.InvariantCulture, out value))
					        numberValue = value;
				        else
					        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
			        }

			        numberType = JsonToken.Float;
		        }
		        else
		        {
			        if (singleDigit)
			        {
				        // digit char values start at 48
				        numberValue = (long) firstChar - 48;
				        numberType = JsonToken.Integer;
			        }
			        else if (nonBase10)
			        {
				        string number = _stringReference.ToString();

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

				        numberType = JsonToken.Integer;
			        }
			        else
			        {
				        long value;
				        ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value);
				        if (parseResult == ParseResult.Success)
				        {
					        numberValue = value;
					        numberType = JsonToken.Integer;
				        }
				        else if (parseResult == ParseResult.Overflow)
				        {
#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
					        string number = _stringReference.ToString();

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

					        numberValue = BigIntegerParse(number, CultureInfo.InvariantCulture);
					        numberType = JsonToken.Integer;
#else
                        throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
#endif
				        }
				        else
				        {
					        string number = _stringReference.ToString();
							switch (_floatParseHandling)
							{
								case FloatParseHandling.Decimal:
									decimal d;
									if (decimal.TryParse(number, numberStyles, CultureInfo.InvariantCulture, out d))
										numberValue = d;
									else
										throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, number));
									break;
								case FloatParseHandling.PreferDecimalFallbackToDouble:
									decimal result;
									if (decimal.TryParse(number, numberStyles, CultureInfo.InvariantCulture, out result) == false)
									{
										goto default;
									}
									numberValue = result;
									break;
								default:
									double d1;
									if (double.TryParse(number, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d1))
										numberValue = d1;
									else
										throw JsonReaderException.Create(this, "Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number));
									break;
							}

					        numberType = JsonToken.Float;
				        }
			        }
		        }
	        }

	        ClearRecentString();

            // index has already been updated
            SetToken(numberType, numberValue, false);
        }
예제 #6
0
        private void ParseConstructor()
        {
            if (MatchValueWithTrailingSeparator("new"))
            {
                EatWhitespace(false);

                int initialPosition = _charPos;
                int endPosition;

                while (true)
                {
                    char currentChar = _chars[_charPos];
                    if (currentChar == '\0')
                    {
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                                throw JsonReaderException.Create(this, "Unexpected end while parsing constructor.");
                        }
                        else
                        {
                            endPosition = _charPos;
                            _charPos++;
                            break;
                        }
                    }
                    else if (char.IsLetterOrDigit(currentChar))
                    {
                        _charPos++;
                    }
                    else if (currentChar == StringUtils.CarriageReturn)
                    {
                        endPosition = _charPos;
                        ProcessCarriageReturn(true);
                        break;
                    }
                    else if (currentChar == StringUtils.LineFeed)
                    {
                        endPosition = _charPos;
                        ProcessLineFeed();
                        break;
                    }
                    else if (char.IsWhiteSpace(currentChar))
                    {
                        endPosition = _charPos;
                        _charPos++;
                        break;
                    }
                    else if (currentChar == '(')
                    {
                        endPosition = _charPos;
                        break;
                    }
                    else
                    {
                        throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
                    }
                }

                _stringReference = new StringReference(_chars, initialPosition, endPosition - initialPosition);
                string constructorName = _stringReference.ToString();

                EatWhitespace(false);

                if (_chars[_charPos] != '(')
                    throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));

                _charPos++;

                ClearRecentString();

                SetToken(JsonToken.StartConstructor, constructorName);
            }
            else
            {
                throw JsonReaderException.Create(this, "Unexpected content while parsing JSON.");
            }
        }
예제 #7
0
		private async Task ParseComment()
		{
			// should have already parsed / character before reaching this method
			_charPos++;

			if (!await EnsureChars(1, false).ConfigureAwait(false) || _chars[_charPos] != '*')
				throw JsonReaderException.Create(this, Path, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]), null);
			else
				_charPos++;

			int initialPosition = _charPos;

			bool commentFinished = false;

			while (!commentFinished)
			{
				switch (_chars[_charPos])
				{
					case '\0':
						if (_charsUsed == _charPos)
						{
							if (await ReadData(true).ConfigureAwait(false) == 0)
								throw JsonReaderException.Create(this, Path, "Unexpected end while parsing comment.", null);
						}
						else
						{
							_charPos++;
						}
						break;
					case '*':
						_charPos++;

						if (await EnsureChars(0, true).ConfigureAwait(false))
						{
							if (_chars[_charPos] == '/')
							{
								_stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1);

								_charPos++;
								commentFinished = true;
							}
						}
						break;
					case StringUtils.CarriageReturn:
						await ProcessCarriageReturn(true).ConfigureAwait(false);
						break;
					case StringUtils.LineFeed:
						ProcessLineFeed();
						break;
					default:
						_charPos++;
						break;
				}
			}

			SetToken(JsonToken.Comment, _stringReference.ToString());

			ClearRecentString();
		}
예제 #8
0
		private async Task ParseNumber()
		{
			ShiftBufferIfNeeded();

			char firstChar = _chars[_charPos];
			int initialPosition = _charPos;

			await ReadNumberIntoBuffer().ConfigureAwait(false);

			_stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);

			object numberValue;
			JsonToken numberType;

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

			if (_readType == ReadType.ReadAsInt32)
			{
				if (singleDigit)
				{
					// digit char values start at 48
					numberValue = firstChar - 48;
				}
				else if (nonBase10)
				{
					string number = _stringReference.ToString();

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

					numberValue = integer;
				}
				else
				{
					string number = _stringReference.ToString();

					numberValue = Convert.ToInt32(number, CultureInfo.InvariantCulture);
				}

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

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

					numberValue = Convert.ToDecimal(integer);
				}
				else
				{
					string number = _stringReference.ToString();

					numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
				}

				numberType = JsonToken.Float;
			}
			else
			{
				if (singleDigit)
				{
					// digit char values start at 48
					numberValue = (long)firstChar - 48;
					numberType = JsonToken.Integer;
				}
				else if (nonBase10)
				{
					string number = _stringReference.ToString();

					numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
									? Convert.ToInt64(number, 16)
									: Convert.ToInt64(number, 8);
					numberType = JsonToken.Integer;
				}
				else
				{
					string number = _stringReference.ToString();

					// it's faster to do 3 indexof with single characters than an indexofany
					if (number.IndexOf('E') != -1 || number.IndexOf('e') != -1)
					{
						numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
						numberType = JsonToken.Float;
					}
					else if (number.IndexOf('.') != -1)
					{
						numberValue = Convert.ToDecimal(number, CultureInfo.InvariantCulture);
						numberType = JsonToken.Float;
					}
					else
					{
						try
						{
							numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
						}
						catch (OverflowException ex)
						{
							throw JsonReaderException.Create(this, Path, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
						}

						numberType = JsonToken.Integer;
					}
				}
			}

			ClearRecentString();

			SetToken(numberType, numberValue);
		}
예제 #9
0
    private void ParseNumber()
    {
      ShiftBufferIfNeeded();

      char firstChar = _chars[_charPos];
      int initialPosition = _charPos;

      ReadNumberIntoBuffer();

      _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);

      object numberValue;
      JsonToken numberType;

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

      if (_readType == ReadType.ReadAsInt32)
      {
        if (singleDigit)
        {
          // digit char values start at 48
          numberValue = firstChar - 48;
        }
        else if (nonBase10)
        {
          string number = _stringReference.ToString();

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

          numberValue = integer;
        }
        else
        {
          numberValue = ConvertUtils.Int32Parse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length);
        }

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

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

          numberValue = Convert.ToDecimal(integer);
        }
        else
        {
          string number = _stringReference.ToString();

          numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
        }

        numberType = JsonToken.Float;
      }
      else
      {
        if (singleDigit)
        {
          // digit char values start at 48
          numberValue = (long)firstChar - 48;
          numberType = JsonToken.Integer;
        }
        else if (nonBase10)
        {
          string number = _stringReference.ToString();

          numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
                          ? Convert.ToInt64(number, 16)
                          : Convert.ToInt64(number, 8);
          numberType = JsonToken.Integer;
        }
        else
        {
          long value;
          ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value);
          if (parseResult == ParseResult.Success)
          {
            numberValue = value;
            numberType = JsonToken.Integer;
          }
          else if (parseResult == ParseResult.Invalid)
          {
            string number = _stringReference.ToString();

            if (_floatParseHandling == FloatParseHandling.Decimal)
              numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
            else
              numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);

            numberType = JsonToken.Float;
          }
          else if (parseResult == ParseResult.Overflow)
          {
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE)
            string number = _stringReference.ToString();
            numberValue = BigInteger.Parse(number, CultureInfo.InvariantCulture);
            numberType = JsonToken.Integer;
#else
            // todo - validate number was a valid integer to make sure overflow was the reason for failure
            throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
#endif
          }
          else
          {
            throw JsonReaderException.Create(this, "Unknown error parsing integer.");
          }
        }
      }

      ClearRecentString();

      SetToken(numberType, numberValue);
    }