예제 #1
0
        public static bool Read(PeepingTomStream stream, UnmanagedJsonParser parser, JsonParserState state, JsonOperationContext.ManagedPinnedBuffer buffer)
        {
            while (parser.Read() == false)
            {
                var read = stream.Read(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Length);
                if (read == 0)
                {
                    if (state.CurrentTokenType != JsonParserToken.EndObject)
                    {
                        throw new EndOfStreamException("Stream ended without reaching end of json content");
                    }

                    return(false);
                }

                parser.SetBuffer(buffer, 0, read);
            }
            return(true);
        }
예제 #2
0
        private bool ParseNumberUnlikely(byte b, ref uint pos, ref long value, JsonParserState state)
        {
            switch (b)
            {
            case (byte)'.':
            {
                if (!_isFractionedDouble)
                {
                    _zeroPrefix         = false; // 0.5, frex
                    _isFractionedDouble = true;
                    break;
                }

                ThrowWhenMalformed("Already got '.' in this number value");
                break;
            }

            case (byte)'+':
                break;     // just record, appears in 1.4e+3

            case (byte)'e':
            case (byte)'E':
            {
                if (_isExponent)
                {
                    ThrowWhenMalformed("Already got 'e' in this number value");
                }
                _isExponent         = true;
                _isFractionedDouble = true;
                break;
            }

            case (byte)'-':
            {
                if (!_isNegative || _isExponent != false)
                {
                    _isNegative = true;
                    break;
                }

                ThrowWhenMalformed("Already got '-' in this number value");
                break;
            }

            case (byte)'\r':
            case (byte)'\n':
            {
                _line++;
                _charPos = 1;

                if (!_zeroPrefix || _unmanagedWriteBuffer.SizeInBytes == 1)
                {
                    if (_isNegative)
                    {
                        value *= -1;
                    }

                    state.CurrentTokenType = (_isFractionedDouble || _isOverflow) ? JsonParserToken.Float : JsonParserToken.Integer;

                    pos--;
                    _charPos--;         // need to re-read this char

                    return(true);
                }

                ThrowWhenMalformed("Invalid number with zero prefix");
                break;
            }
            }

            return(false);
        }
예제 #3
0
        private bool ParseNumber(ref long value, ref uint pos)
        {
            JsonParserState state = _state;

            uint  bufferSize  = _bufSize;
            byte *inputBuffer = _inputBuffer;

            while (true)
            {
                if (pos >= bufferSize)
                {
                    goto NotANumber;
                }

                byte b     = inputBuffer[pos];
                byte digit = (byte)(b - (byte)'0');

                _charPos++;
                pos++;
                if (digit <= 9) // PERF: Simplified the check to get rid of 1 comparison
                {
                    // PERF: This is a fast loop for the most common characters found on numbers.
                    var next = (value * 10) + digit;

                    if (next < value) //overflow
                    {
                        _isOverflow = true;
                    }

                    value = next;


                    _unmanagedWriteBuffer.WriteByte(b);

                    continue;
                }

                if (b == ' ' || b == ',' || b == '}' || b == ']' || ParseNumberTable[b] == ParseNumberAction.ParseEnd)
                {
                    if (!_zeroPrefix || _unmanagedWriteBuffer.SizeInBytes == 1)
                    {
                        if (_isNegative)
                        {
                            value *= -1;
                        }

                        state.CurrentTokenType = (_isFractionedDouble || _isOverflow) ? JsonParserToken.Float : JsonParserToken.Integer;

                        pos--;
                        _charPos--;// need to re-read this char

                        goto IsANumber;
                    }

                    ThrowWhenMalformed("Invalid number with zero prefix");
                    break;
                }

                if (ParseNumberTable[b] == ParseNumberAction.ParseUnlikely)
                {
                    if (ParseNumberUnlikely(b, ref pos, ref value, state))
                    {
                        goto IsANumber;
                    }

                    _unmanagedWriteBuffer.WriteByte(b);
                    continue;
                }

                // No hit, we are done.
                ThrowWhenMalformed("Number cannot end with char with: '" + (char)b + "' (" + b + ")");
            }

IsANumber:
            return(true);

NotANumber:
            return(false); // Will never execute.
        }
예제 #4
0
        public static unsafe string ReadString(JsonOperationContext context, PeepingTomStream peepingTomStream, UnmanagedJsonParser parser, JsonParserState state, JsonOperationContext.ManagedPinnedBuffer buffer)
        {
            if (Read(peepingTomStream, parser, state, buffer) == false)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            if (state.CurrentTokenType == JsonParserToken.Null)
            {
                return(null);
            }

            if (state.CurrentTokenType != JsonParserToken.String)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            return(context.AllocateStringValue(null, state.StringBuffer, state.StringSize).ToString());
        }
예제 #5
0
        public static async Task <bool> ReadAsync(PeepingTomStream peepingTomStream, UnmanagedJsonParser parser, JsonParserState state, JsonOperationContext.ManagedPinnedBuffer buffer)
        {
            if (parser.Read())
            {
                return(true);
            }

            var read = await peepingTomStream.ReadAsync(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Length).ConfigureAwait(false);

            if (read == 0)
            {
                if (state.CurrentTokenType != JsonParserToken.EndObject)
                {
                    throw new EndOfStreamException("Stream ended without reaching end of json content");
                }

                return(false);
            }

            parser.SetBuffer(buffer, 0, read);
            return(parser.Read());
        }
예제 #6
0
        public static IEnumerable <BlittableJsonReaderObject> ReadArrayToMemory(JsonOperationContext context, PeepingTomStream peepingTomStream, UnmanagedJsonParser parser, JsonParserState state, JsonOperationContext.ManagedPinnedBuffer buffer)
        {
            if (Read(peepingTomStream, parser, state, buffer) == false)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            if (state.CurrentTokenType != JsonParserToken.StartArray)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            while (true)
            {
                if (Read(peepingTomStream, parser, state, buffer) == false)
                {
                    ThrowInvalidJson(peepingTomStream);
                }

                if (state.CurrentTokenType == JsonParserToken.EndArray)
                {
                    break;
                }

                using (var builder = new BlittableJsonDocumentBuilder(context, BlittableJsonDocumentBuilder.UsageMode.None, "readArray/singleResult", parser, state))
                {
                    ReadObject(builder, peepingTomStream, parser, buffer);

                    yield return(builder.CreateReader());
                }
            }
        }
예제 #7
0
        public static long ReadLong(JsonOperationContext context, PeepingTomStream peepingTomStream, UnmanagedJsonParser parser, JsonParserState state, JsonOperationContext.ManagedPinnedBuffer buffer)
        {
            if (Read(peepingTomStream, parser, state, buffer) == false)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            if (state.CurrentTokenType != JsonParserToken.Integer)
            {
                ThrowInvalidJson(peepingTomStream);
            }

            return(state.Long);
        }