/// <summary> /// Read from the stream until either our buffer is filled or we hit EOF. /// Calling ReadCore is relatively expensive, so we minimize the number of times /// we need to call it. /// </summary> internal static async ValueTask <ReadBufferState> ReadFromStreamAsync( Stream utf8Json, ReadBufferState bufferState, CancellationToken cancellationToken) { while (true) { int bytesRead = await utf8Json.ReadAsync( #if BUILDING_INBOX_LIBRARY bufferState.Buffer.AsMemory(bufferState.BytesInBuffer), #else bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer, #endif cancellationToken).ConfigureAwait(false); if (bytesRead == 0) { bufferState.IsFinalBlock = true; break; } bufferState.BytesInBuffer += bytesRead; if (bufferState.BytesInBuffer == bufferState.Buffer.Length) { break; } } return(bufferState); }
static async IAsyncEnumerable <TValue> CreateAsyncEnumerableDeserializer( Stream utf8Json, JsonSerializerOptions options, [EnumeratorCancellation] CancellationToken cancellationToken) { var bufferState = new ReadBufferState(options.DefaultBufferSize); // Hardcode the queue converter to avoid accidental use of custom converters JsonConverter converter = QueueOfTConverter <Queue <TValue>, TValue> .Instance; JsonTypeInfo jsonTypeInfo = CreateQueueJsonTypeInfo <TValue>(converter, options); ReadStack readStack = default; readStack.Initialize(jsonTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); try { do { bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false); ContinueDeserialize <Queue <TValue> >(ref bufferState, ref jsonReaderState, ref readStack, converter, options); if (readStack.Current.ReturnValue is Queue <TValue> queue) { while (queue.Count > 0) { yield return(queue.Dequeue()); } } }while (!bufferState.IsFinalBlock); } finally { bufferState.Dispose(); } }
/// <summary> /// Read from the stream until either our buffer is filled or we hit EOF. /// Calling ReadCore is relatively expensive, so we minimize the number of times /// we need to call it. /// </summary> internal static ReadBufferState ReadFromStream( Stream utf8Json, ReadBufferState bufferState) { while (true) { int bytesRead = utf8Json.Read( #if BUILDING_INBOX_LIBRARY bufferState.Buffer.AsSpan(bufferState.BytesInBuffer)); #else bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer); #endif if (bytesRead == 0) { bufferState.IsFinalBlock = true; break; } bufferState.BytesInBuffer += bytesRead; if (bufferState.BytesInBuffer == bufferState.Buffer.Length) { break; } } return(bufferState); }
private void OnRead(IAsyncResult base_ares) { ReadBufferState rb = (ReadBufferState)base_ares.AsyncState; HttpStreamAsyncResult ares = rb.Ares; try { int nread = base.EndRead(base_ares); _decoder.Write(ares._buffer, ares._offset, nread); nread = _decoder.Read(rb.Buffer, rb.Offset, rb.Count); rb.Offset += nread; rb.Count -= nread; if (rb.Count == 0 || !_decoder.WantMore || nread == 0) { _no_more_data = !_decoder.WantMore && nread == 0; ares._count = rb.InitialCount - rb.Count; ares.Complete(); return; } ares._offset = 0; ares._count = Math.Min(8192, _decoder.ChunkLeft + 6); base.BeginRead(ares._buffer, ares._offset, ares._count, OnRead, rb); } catch (Exception e) { _context.Connection.SendError(e.Message, 400); ares.Complete(e); } }
internal static TValue?ReadAll <TValue>( Stream utf8Json, JsonTypeInfo jsonTypeInfo) { JsonSerializerOptions options = jsonTypeInfo.Options; var bufferState = new ReadBufferState(options.DefaultBufferSize); ReadStack readStack = default; jsonTypeInfo.EnsureConfigured(); readStack.Initialize(jsonTypeInfo, supportContinuation: true); JsonConverter converter = readStack.Current.JsonPropertyInfo !.ConverterBase; var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); try { while (true) { bufferState = ReadFromStream(utf8Json, bufferState); TValue value = ContinueDeserialize <TValue>(ref bufferState, ref jsonReaderState, ref readStack, converter, options); if (bufferState.IsFinalBlock) { return(value !); } } } finally { bufferState.Dispose(); } }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) { if (_disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } int len = buffer.Length; if (offset < 0 || offset > len) { throw new ArgumentOutOfRangeException(nameof(offset), SR.offset_out_of_range); } if (count < 0 || offset > len - count) { throw new ArgumentOutOfRangeException(nameof(count), SR.offset_out_of_range); } HttpStreamAsyncResult ares = new HttpStreamAsyncResult(); ares._callback = cback; ares._state = state; if (_no_more_data) { ares.Complete(); return(ares); } int nread = _decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet ares._count = nread; ares.Complete(); return(ares); } if (!_decoder.WantMore) { _no_more_data = nread == 0; ares._count = nread; ares.Complete(); return(ares); } ares._buffer = new byte[8192]; ares._offset = 0; ares._count = 8192; ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares); rb.InitialCount += nread; base.BeginRead(ares._buffer, ares._offset, ares._count, OnRead, rb); return(ares); }
private void OnRead(IAsyncResult base_ares) { ReadBufferState readBufferState = (ReadBufferState)base_ares.AsyncState; HttpStreamAsyncResult ares = readBufferState.Ares; try { int size = base.EndRead(base_ares); decoder.Write(ares.Buffer, ares.Offset, size); size = decoder.Read(readBufferState.Buffer, readBufferState.Offset, readBufferState.Count); readBufferState.Offset += size; readBufferState.Count -= size; if (readBufferState.Count == 0 || !decoder.WantMore || size == 0) { no_more_data = (!decoder.WantMore && size == 0); ares.Count = readBufferState.InitialCount - readBufferState.Count; ares.Complete(); } else { ares.Offset = 0; ares.Count = Math.Min(8192, decoder.ChunkLeft + 6); base.BeginRead(ares.Buffer, ares.Offset, ares.Count, (AsyncCallback)OnRead, (object)readBufferState); } } catch (Exception ex) { context.Connection.SendError(ex.Message, 400); ares.Complete(ex); } }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) { if (disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException("buffer"); } int num = buffer.Length; if (offset < 0 || offset > num) { throw new ArgumentOutOfRangeException("offset exceeds the size of buffer"); } if (count < 0 || offset > num - count) { throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer"); } HttpStreamAsyncResult httpStreamAsyncResult = new HttpStreamAsyncResult(); httpStreamAsyncResult.Callback = cback; httpStreamAsyncResult.State = state; if (no_more_data) { httpStreamAsyncResult.Complete(); return(httpStreamAsyncResult); } int num2 = decoder.Read(buffer, offset, count); offset += num2; count -= num2; if (count == 0) { httpStreamAsyncResult.Count = num2; httpStreamAsyncResult.Complete(); return(httpStreamAsyncResult); } if (!decoder.WantMore) { no_more_data = (num2 == 0); httpStreamAsyncResult.Count = num2; httpStreamAsyncResult.Complete(); return(httpStreamAsyncResult); } httpStreamAsyncResult.Buffer = new byte[8192]; httpStreamAsyncResult.Offset = 0; httpStreamAsyncResult.Count = 8192; ReadBufferState readBufferState = new ReadBufferState(buffer, offset, count, httpStreamAsyncResult); readBufferState.InitialCount += num2; base.BeginRead(httpStreamAsyncResult.Buffer, httpStreamAsyncResult.Offset, httpStreamAsyncResult.Count, (AsyncCallback)OnRead, (object)readBufferState); return(httpStreamAsyncResult); }
private static async IAsyncEnumerable <TValue> CreateAsyncEnumerableDeserializer <TValue>( Stream utf8Json, JsonTypeInfo jsonTypeInfo, [EnumeratorCancellation] CancellationToken cancellationToken) { JsonSerializerOptions options = jsonTypeInfo.Options; JsonTypeInfo <Queue <TValue> > queueTypeInfo = JsonMetadataServices.CreateQueueInfo <Queue <TValue>, TValue>( options: options, collectionInfo: new() { ObjectCreator = () => new Queue <TValue>(), ElementInfo = jsonTypeInfo, NumberHandling = options.NumberHandling }); var bufferState = new ReadBufferState(options.DefaultBufferSize); ReadStack readStack = default; queueTypeInfo.EnsureConfigured(); readStack.Initialize(queueTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); try { do { bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false); ContinueDeserialize <Queue <TValue> >( ref bufferState, ref jsonReaderState, ref readStack, queueTypeInfo.PropertyInfoForTypeInfo.ConverterBase, options); if (readStack.Current.ReturnValue is Queue <TValue> queue) { while (queue.Count > 0) { yield return(queue.Dequeue()); } } }while (!bufferState.IsFinalBlock); } finally { bufferState.Dispose(); } }
protected override IAsyncResult BeginReadCore(byte[] buffer, int offset, int size, AsyncCallback cback, object state) { HttpStreamAsyncResult ares = new HttpStreamAsyncResult(this); ares._callback = cback; ares._state = state; if (_no_more_data || size == 0 || _closed) { ares.Complete(); return(ares); } int nread = _decoder.Read(buffer, offset, size); offset += nread; size -= nread; if (size == 0) { // got all we wanted, no need to bother the decoder yet ares._count = nread; ares.Complete(); return(ares); } if (!_decoder.WantMore) { _no_more_data = nread == 0; ares._count = nread; ares.Complete(); return(ares); } ares._buffer = new byte[8192]; ares._offset = 0; ares._count = 8192; ReadBufferState rb = new ReadBufferState(buffer, offset, size, ares); rb.InitialCount += nread; base.BeginReadCore(ares._buffer, ares._offset, ares._count, OnRead, rb); return(ares); }
internal static TValue ContinueDeserialize <TValue>( ref ReadBufferState bufferState, ref JsonReaderState jsonReaderState, ref ReadStack readStack, JsonConverter converter, JsonSerializerOptions options) { if (bufferState.BytesInBuffer > bufferState.ClearMax) { bufferState.ClearMax = bufferState.BytesInBuffer; } int start = 0; if (bufferState.IsFirstIteration) { bufferState.IsFirstIteration = false; // Handle the UTF-8 BOM if present Debug.Assert(bufferState.Buffer.Length >= JsonConstants.Utf8Bom.Length); if (bufferState.Buffer.AsSpan().StartsWith(JsonConstants.Utf8Bom)) { start += JsonConstants.Utf8Bom.Length; bufferState.BytesInBuffer -= JsonConstants.Utf8Bom.Length; } } // Process the data available TValue value = ReadCore <TValue>( ref jsonReaderState, bufferState.IsFinalBlock, new ReadOnlySpan <byte>(bufferState.Buffer, start, bufferState.BytesInBuffer), options, ref readStack, converter); Debug.Assert(readStack.BytesConsumed <= bufferState.BytesInBuffer); int bytesConsumed = checked ((int)readStack.BytesConsumed); bufferState.BytesInBuffer -= bytesConsumed; // The reader should have thrown if we have remaining bytes. Debug.Assert(!bufferState.IsFinalBlock || bufferState.BytesInBuffer == 0); if (!bufferState.IsFinalBlock) { // Check if we need to shift or expand the buffer because there wasn't enough data to complete deserialization. if ((uint)bufferState.BytesInBuffer > ((uint)bufferState.Buffer.Length / 2)) { // We have less than half the buffer available, double the buffer size. byte[] oldBuffer = bufferState.Buffer; int oldClearMax = bufferState.ClearMax; byte[] newBuffer = ArrayPool <byte> .Shared.Rent((bufferState.Buffer.Length < (int.MaxValue / 2))?bufferState.Buffer.Length * 2 : int.MaxValue); // Copy the unprocessed data to the new buffer while shifting the processed bytes. Buffer.BlockCopy(oldBuffer, bytesConsumed + start, newBuffer, 0, bufferState.BytesInBuffer); bufferState.Buffer = newBuffer; bufferState.ClearMax = bufferState.BytesInBuffer; // Clear and return the old buffer new Span <byte>(oldBuffer, 0, oldClearMax).Clear(); ArrayPool <byte> .Shared.Return(oldBuffer); } else if (bufferState.BytesInBuffer != 0) { // Shift the processed bytes to the beginning of buffer to make more room. Buffer.BlockCopy(bufferState.Buffer, bytesConsumed + start, bufferState.Buffer, 0, bufferState.BytesInBuffer); } } return(value); }
public new IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) { if (_disposed) throw new ObjectDisposedException(GetType().ToString()); if (buffer == null) throw new ArgumentNullException(nameof(buffer)); var len = buffer.Length; if (offset < 0 || offset > len) throw new ArgumentOutOfRangeException("offset exceeds the size of buffer"); if (count < 0 || offset > len - count) throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer"); var ares = new HttpStreamAsyncResult { Callback = cback, State = state }; if (_noMoreData) { ares.Complete(); return ares; } var nread = Decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet ares.Count = nread; ares.Complete(); return ares; } if (!Decoder.WantMore) { _noMoreData = nread == 0; ares.Count = nread; ares.Complete(); return ares; } ares.Buffer = new byte[8192]; ares.Offset = 0; ares.Count = 8192; var rb = new ReadBufferState(buffer, offset, count, ares); rb.InitialCount += nread; base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb); return ares; }
public new IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) { if (_disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } var len = buffer.Length; if (offset < 0 || offset > len) { throw new ArgumentOutOfRangeException(nameof(offset), "offset exceeds the size of buffer"); } if (count < 0 || offset > len - count) { throw new ArgumentOutOfRangeException(nameof(offset), "offset+size exceeds the size of buffer"); } var ares = new HttpStreamAsyncResult { Callback = cback, State = state }; if (_noMoreData) { ares.Complete(); return(ares); } var nread = Decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet ares.Count = nread; ares.Complete(); return(ares); } if (!Decoder.WantMore) { _noMoreData = nread == 0; ares.Count = nread; ares.Complete(); return(ares); } ares.Buffer = new byte[8192]; ares.Offset = 0; ares.Count = 8192; var rb = new ReadBufferState(buffer, offset, count, ares); rb.InitialCount += nread; base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb); return(ares); }
public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token) { if (disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException("buffer"); } int len = buffer.Length; if (offset < 0 || offset > len) { throw new ArgumentOutOfRangeException("offset exceeds the size of buffer"); } if (count < 0 || offset > len - count) { throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer"); } if (no_more_data) { return(0); } int nread = decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet return(nread); } if (!decoder.WantMore) { no_more_data = nread == 0; return(nread); } ReadBufferState rb = new ReadBufferState(buffer, offset, count, null); rb.InitialCount += nread; var readBuff = new byte[8192]; var readCount = 8192; try { while (true) { nread = await base.ReadAsync(readBuff, 0, readCount, token); decoder.Write(readBuff, 0, nread); nread = decoder.Read(rb.Buffer, rb.Offset, rb.Count); rb.Offset += nread; rb.Count -= nread; if (rb.Count == 0 || !decoder.WantMore || nread == 0) { no_more_data = !decoder.WantMore && nread == 0; return(rb.InitialCount - rb.Count); } readCount = System.Math.Min(8192, decoder.ChunkLeft + 6); } } catch (Exception e) { context.Connection.SendError(e.Message, 400); return(0); } }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) { if (disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException("buffer"); } int len = buffer.Length; if (offset < 0 || offset > len) { throw new ArgumentOutOfRangeException("offset exceeds the size of buffer"); } if (count < 0 || offset > len - count) { throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer"); } HttpStreamAsyncResult ares = new HttpStreamAsyncResult(); ares.Callback = cback; ares.State = state; if (no_more_data) { ares.Complete(); return ares; } int nread = decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet ares.Count = nread; ares.Complete(); return ares; } if (!decoder.WantMore) { no_more_data = nread == 0; ares.Count = nread; ares.Complete(); return ares; } ares.Buffer = new byte[8192]; ares.Offset = 0; ares.Count = 8192; ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares); rb.InitialCount += nread; base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb); return ares; }
public override IAsyncResult BeginRead( byte [] buffer, int offset, int count, AsyncCallback cback, object state) { if (disposed) { throw new ObjectDisposedException(GetType().ToString()); } if (buffer == null) { throw new ArgumentNullException("buffer"); } int len = buffer.Length; if (offset < 0 || offset > len) { throw new ArgumentOutOfRangeException("'offset' exceeds the size of buffer."); } if (count < 0 || offset > len - count) { throw new ArgumentOutOfRangeException("'offset' + 'count' exceeds the size of buffer."); } var ares = new HttpStreamAsyncResult(); ares.Callback = cback; ares.State = state; if (no_more_data) { ares.Complete(); return(ares); } int nread = decoder.Read(buffer, offset, count); offset += nread; count -= nread; if (count == 0) { // got all we wanted, no need to bother the decoder yet ares.Count = nread; ares.Complete(); return(ares); } if (!decoder.WantMore) { no_more_data = nread == 0; ares.Count = nread; ares.Complete(); return(ares); } ares.Buffer = new byte [8192]; ares.Offset = 0; ares.Count = 8192; var rb = new ReadBufferState(buffer, offset, count, ares); rb.InitialCount += nread; base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb); return(ares); }