public static async Task CopyToAsync(this IReadableChannel input, Stream stream) { while (true) { await input; var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } foreach (var span in inputBuffer) { await stream.WriteAsync(span.Array, span.Offset, span.Length); } } catch (Exception) { // REVIEW: Should we do anything here? } finally { input.EndRead(inputBuffer); } } }
public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel channel) { while (true) { await input; var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = channel.Alloc(); buffer.Append(inputBuffer); await channel.WriteAsync(buffer); } finally { input.EndRead(inputBuffer); } } }
public static async Task CopyToAsync(this IReadableChannel input, Stream stream) { while (true) { await input; var fin = input.Completion.IsCompleted; var span = input.BeginRead(); if (span.Begin.IsEnd && fin) { return; } try { await span.Begin.CopyToAsync(stream, span.End.Block); } finally { input.EndRead(span.End); } } }
private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel) { await input; do { var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); try { if (inputBuffer.IsEmpty && fin) { return; } var buffer = channel.Alloc(); buffer.Append(inputBuffer); await channel.WriteAsync(buffer); } finally { input.EndRead(inputBuffer); } }while (input.IsCompleted); }
private static async Task ReadLines(IReadableChannel channel) { // Using SIMD to scan through bytes quickly var newLine = new Vector <byte>((byte)'\n'); while (true) { await channel; var iter = channel.BeginRead().Begin; var start = iter; // If we're at the end of the channel then stop if (iter.IsEnd && channel.Completion.IsCompleted) { break; } try { while (iter.Seek(ref newLine) != -1) { // Get the daata from the start to where we found the \n var line = start.GetArraySegment(iter); Console.WriteLine(Encoding.UTF8.GetString(line.Array, line.Offset, line.Count)); // Skip /n iter.Skip(1); start = iter; } } finally { channel.EndRead(iter); } } // Tell te channel we're done consuming channel.CompleteReading(); }
private async void Process(IReadableChannel inner) { while (true) { await inner; var span = inner.BeginRead(); if (span.Begin.IsEnd && inner.Completion.IsCompleted) { break; } // PERF: This might copy var data = span.Begin.GetArraySegment(span.End); var iter = _channel.BeginWrite(); for (int i = 0; i < data.Count; i++) { byte b = data.Array[data.Offset + i]; if (b >= 'a' && b <= 'z') { // To upper iter.Write((byte)(b & 0xdf)); } else { // Leave it alone iter.Write(b); } } await _channel.EndWriteAsync(iter); inner.EndRead(span.End); } inner.CompleteReading(); _channel.CompleteWriting(); }
public async Task Execute(IReadableChannel input, IWritableChannel output) { while (true) { await input; var inputBuffer = input.BeginRead(); if (inputBuffer.IsEmpty && input.Completion.IsCompleted) { break; } var writerBuffer = output.Alloc(2048); var span = inputBuffer.FirstSpan; if (span.Length > 0) { _inflater.SetInput(span.BufferPtr, span.Length); int written = _inflater.Inflate(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length); writerBuffer.UpdateWritten(written); var consumed = span.Length - _inflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); } input.EndRead(inputBuffer); await output.WriteAsync(writerBuffer); } input.CompleteReading(); output.CompleteWriting(); _inflater.Dispose(); }
private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, byte[] buffer, int offset, int count) { while (true) { await input; var fin = input.Completion.IsCompleted; var begin = input.BeginRead().Begin; int actual; var end = begin.CopyTo(buffer, offset, count, out actual); input.EndRead(end); if (actual != 0) { return(actual); } else if (fin) { return(0); } } }
public static ValueTask <int> ReadAsync(this IReadableChannel input, byte[] buffer, int offset, int count) { while (input.IsCompleted) { var fin = input.Completion.IsCompleted; var begin = input.BeginRead().Begin; int actual; var end = begin.CopyTo(buffer, offset, count, out actual); input.EndRead(end); if (actual != 0) { return(new ValueTask <int>(actual)); } else if (fin) { return(new ValueTask <int>(0)); } } return(new ValueTask <int>(input.ReadAsyncAwaited(buffer, offset, count))); }
public static ValueTask <int> ReadAsync(this IReadableChannel input, byte[] buffer, int offset, int count) { while (input.IsCompleted) { var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); var sliced = inputBuffer.Slice(0, count); sliced.CopyTo(buffer, offset); int actual = sliced.Length; input.EndRead(sliced); if (actual != 0) { return(new ValueTask <int>(actual)); } else if (fin) { return(new ValueTask <int>(0)); } } return(new ValueTask <int>(input.ReadAsyncAwaited(buffer, offset, count))); }
private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, byte[] buffer, int offset, int count) { while (true) { await input; var fin = input.Completion.IsCompleted; var inputBuffer = input.BeginRead(); var sliced = inputBuffer.Slice(0, count); sliced.CopyTo(buffer, offset); int actual = sliced.Length; input.EndRead(sliced); if (actual != 0) { return(actual); } else if (fin) { return(0); } } }
public static void EndRead(this IReadableChannel input, ReadableBuffer consumed) { input.EndRead(consumed.End, consumed.End); }
public static void EndRead(this IReadableChannel input, ReadIterator consumed) { input.EndRead(consumed, consumed); }
public async Task Execute(IReadableChannel input, IWritableChannel output) { while (true) { await input; var inputBuffer = input.BeginRead(); if (inputBuffer.IsEmpty && input.Completion.IsCompleted) { break; } var writerBuffer = output.Alloc(2048); var span = inputBuffer.FirstSpan; _deflater.SetInput(span.BufferPtr, span.Length); while (!_deflater.NeedsInput()) { int written = _deflater.ReadDeflateOutput(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length); writerBuffer.UpdateWritten(written); } var consumed = span.Length - _deflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); input.EndRead(inputBuffer); await output.WriteAsync(writerBuffer); } bool flushed; do { // Need to do more stuff here var writerBuffer = output.Alloc(2048); int compressedBytes; flushed = _deflater.Flush(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length, out compressedBytes); writerBuffer.UpdateWritten(compressedBytes); await output.WriteAsync(writerBuffer); }while (flushed); bool finished; do { // Need to do more stuff here var writerBuffer = output.Alloc(2048); int compressedBytes; finished = _deflater.Finish(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length, out compressedBytes); writerBuffer.UpdateWritten(compressedBytes); await output.WriteAsync(writerBuffer); }while (!finished); input.CompleteReading(); output.CompleteWriting(); _deflater.Dispose(); }
public async Task ProcessAllRequests() { Reset(); while (true) { await _input; var buffer = _input.BeginRead(); var consumed = buffer.Start; bool needMoreData = true; try { if (buffer.IsEmpty && _input.Completion.IsCompleted) { // We're done with this connection return; } if (_state == ParsingState.StartLine) { // Find \n var delim = buffer.IndexOf(ref _vectorLFs); if (delim.IsEnd) { continue; } // Grab the entire start line var startLine = buffer.Slice(0, delim); // Move the buffer to the rest buffer = buffer.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorSpaces); if (delim.IsEnd) { throw new Exception(); } var method = startLine.Slice(0, delim); Method = method.Clone(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorSpaces); if (delim.IsEnd) { throw new Exception(); } var path = startLine.Slice(0, delim); Path = path.Clone(); // Skip ' ' startLine = startLine.Slice(delim).Slice(1); delim = startLine.IndexOf(ref _vectorCRs); if (delim.IsEnd) { throw new Exception(); } var httpVersion = startLine.Slice(0, delim); HttpVersion = httpVersion.Clone(); _state = ParsingState.Headers; consumed = startLine.End; } // Parse headers // key: value\r\n while (!buffer.IsEmpty) { var ch = buffer.Peek(); if (ch == -1) { break; } if (ch == '\r') { // Check for final CRLF. buffer = buffer.Slice(1); ch = buffer.Peek(); buffer = buffer.Slice(1); if (ch == -1) { break; } else if (ch == '\n') { consumed = buffer.Start; needMoreData = false; break; } // Headers don't end in CRLF line. throw new Exception(); } var headerName = default(ReadableBuffer); var headerValue = default(ReadableBuffer); // End of the header // \n var delim = buffer.IndexOf(ref _vectorLFs); if (delim.IsEnd) { break; } var headerPair = buffer.Slice(0, delim); buffer = buffer.Slice(delim).Slice(1); // : delim = headerPair.IndexOf(ref _vectorColons); if (delim.IsEnd) { throw new Exception(); } headerName = headerPair.Slice(0, delim).TrimStart(); headerPair = headerPair.Slice(delim).Slice(1); // \r delim = headerPair.IndexOf(ref _vectorCRs); if (delim.IsEnd) { // Bad request throw new Exception(); } headerValue = headerPair.Slice(0, delim).TrimStart(); RequestHeaders.SetHeader(ref headerName, ref headerValue); // Move the consumed consumed = buffer.Start; } } catch (Exception) { StatusCode = 400; await EndResponse(); return; } finally { _input.EndRead(consumed); } if (needMoreData) { continue; } var context = _application.CreateContext(this); try { await _application.ProcessRequestAsync(context); } catch (Exception ex) { StatusCode = 500; _application.DisposeContext(context, ex); } finally { await EndResponse(); } if (!KeepAlive) { break; } Reset(); } }