Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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
            }
        }