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); }
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); }
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. }
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()); }
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()); }
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()); } } }
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); }