private bool ParseNumber() { while (true) { if (_pos >= _bufSize) { return(false); } _charPos++; var b = _inputBuffer[_pos++]; switch (b) { case (byte)'.': if (_isDouble) { throw CreateException("Already got '.' in this number value"); } _zeroPrefix = false; // 0.5, frex _isDouble = true; break; case (byte)'+': break; // just record, appears in 1.4e+3 case (byte)'e': case (byte)'E': if (_isExponent) { throw CreateException("Already got 'e' in this number value"); } _isExponent = true; _isDouble = true; break; case (byte)'-': if (_isNegative) { throw CreateException("Already got '-' in this number value"); } _isNegative = true; break; case (byte)'0': case (byte)'1': case (byte)'2': case (byte)'3': case (byte)'4': case (byte)'5': case (byte)'6': case (byte)'7': case (byte)'8': case (byte)'9': _state.Long *= 10; _state.Long += b - (byte)'0'; break; default: switch (b) { case (byte)'\r': case (byte)'\n': _line++; _charPos = 1; goto case (byte)' '; case (byte)' ': case (byte)'\t': case (byte)'\v': case (byte)'\f': case (byte)',': case (byte)']': case (byte)'}': if (_zeroPrefix && _stringBuffer.SizeInBytes != 1) { throw CreateException("Invalid number with zero prefix"); } if (_isNegative) { _state.Long *= -1; } _state.CurrentTokenType = _isDouble ? JsonParserToken.Float : JsonParserToken.Integer; _pos--; _charPos--; // need to re-read this char return(true); default: throw CreateException("Number cannot end with char with: '" + (char)b + "' (" + b + ")"); } } _stringBuffer.WriteByte(b); } }
private bool ContinueParsingValue() { switch (_state.Continuation) { case JsonParserTokenContinuation.PartialNegativeInfinity: // here we need to check if we have a negative number or negative // infinity if (_expectedTokenBufferPosition == 1 && _inputBuffer[_pos] != (byte)'I') { _zeroPrefix = false; _isNegative = true; _isFractionedDouble = false; _isOverflow = false; _isExponent = false; _state.Long = 0; _state.EscapePositions.Clear(); _unmanagedWriteBuffer.Clear(); _unmanagedWriteBuffer.WriteByte((byte)'-'); _state.Continuation = JsonParserTokenContinuation.PartialNumber; goto case JsonParserTokenContinuation.PartialNumber; } goto case JsonParserTokenContinuation.PartialPositiveInfinity; case JsonParserTokenContinuation.PartialNaN: case JsonParserTokenContinuation.PartialPositiveInfinity: { if (EnsureRestOfToken(ref _pos) == false) { return(false); } _state.Continuation = JsonParserTokenContinuation.None; _state.CurrentTokenType = JsonParserToken.Float; _unmanagedWriteBuffer.Write(_expectedTokenBuffer, 0, _expectedTokenBuffer.Length); _unmanagedWriteBuffer.EnsureSingleChunk(_state); return(true); } case JsonParserTokenContinuation.PartialNumber: { if (ParseNumber(ref _state.Long, ref _pos) == false) { return(false); } if (_state.CurrentTokenType == JsonParserToken.Float) { _unmanagedWriteBuffer.EnsureSingleChunk(_state); } _state.Continuation = JsonParserTokenContinuation.None; return(true); } case JsonParserTokenContinuation.PartialPreamble: { if (EnsureRestOfToken(ref _pos) == false) { return(false); } _state.Continuation = JsonParserTokenContinuation.None; return(false); } case JsonParserTokenContinuation.PartialString: { if (ParseString(ref _pos) == false) { return(false); } _unmanagedWriteBuffer.EnsureSingleChunk(_state); _state.CurrentTokenType = JsonParserToken.String; _state.Continuation = JsonParserTokenContinuation.None; return(true); } case JsonParserTokenContinuation.PartialFalse: { if (EnsureRestOfToken(ref _pos) == false) { return(false); } _state.CurrentTokenType = JsonParserToken.False; _state.Continuation = JsonParserTokenContinuation.None; return(true); } case JsonParserTokenContinuation.PartialTrue: { if (EnsureRestOfToken(ref _pos) == false) { return(false); } _state.CurrentTokenType = JsonParserToken.True; _state.Continuation = JsonParserTokenContinuation.None; return(true); } case JsonParserTokenContinuation.PartialNull: { if (EnsureRestOfToken(ref _pos) == false) { return(false); } _state.CurrentTokenType = JsonParserToken.Null; _state.Continuation = JsonParserTokenContinuation.None; return(true); } default: ThrowException("Somehow got continuation for single byte token " + _state.Continuation); return(false); // never hit } }