public ProtocolProcessingBehavior ProcessBufferForMessage(IConnection connection, IMessagePipeline pipeline, ref ReadOnlySequence <byte> buffer) { SequencePosition?position = null; var pipelineResult = PipelineResult.Continue; do { position = buffer.PositionOfAny(_sentinels); if (position == null) { continue; } pipelineResult = pipeline.ProcessMessage(connection, buffer.Slice(0, position.Value).ToArray(), this.DefaultResponse); buffer = buffer.Slice(buffer.GetPosition(1 + _readPastLength, position.Value)); } while (position != null && pipelineResult == PipelineResult.Continue); if (pipelineResult == PipelineResult.StopAndDisconnect) { return(ProtocolProcessingBehavior.Disconnect); } return(ProtocolProcessingBehavior.ContinueProcessing); }
private static async Task <string?> PipeReadLine(this PipeReader reader, Encoding encoding) { byte[] testChars = new byte[] { (byte)'\n', (byte)'\r' }; while (true) { ReadResult result = await reader.ReadAsync().ConfigureAwait(false); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition? position = buffer.PositionOfAny(testChars); if (position is null) { if (result.IsCompleted) { if (buffer.Length == 0) { return(null); } string rtn = encoding.GetString(buffer.ToArray()); reader.AdvanceTo(buffer.End); return(rtn); } reader.AdvanceTo(buffer.Start, buffer.End); } else { ReadOnlySequence <byte> line = buffer.Slice(0, position.Value); string linestring = encoding.GetString(line.ToArray()); reader.AdvanceTo(line.End); while (true) { result = await reader.ReadAsync().ConfigureAwait(false); buffer = result.Buffer; if (buffer.Length == 1) { // if the size is 1 and its completed just advance to end if (result.IsCompleted) { reader.AdvanceTo(buffer.End); break; } // if the size is 1 and there is more signal that we need more so we can read \r\n reader.AdvanceTo(buffer.Start, buffer.GetPosition(1)); } else if (buffer.Length > 1) { char c = (char)buffer.GetAt(0); long advances = 0; // \n - UNIX \r\n - DOS \r - Mac switch (c) { // if its a \r advance one position and check if next char is a \n case '\r': advances++; if (buffer.GetAt(1) == '\n') { advances++; } break; // if its a \n just advance one position case '\n': advances++; break; } reader.AdvanceTo(buffer.GetPosition(advances)); break; } else if (result.IsCompleted) { reader.AdvanceTo(buffer.End); break; } } return(linestring); } } }