static async Task ReadFromPipe(PipeReader reader, Action <ReadOnlySequence <byte> > operation) { while (true) { var readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; SequencePosition? position = null; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var line = buffer.Slice(0, position.Value); operation?.Invoke(line); var next = buffer.GetPosition(1, position.Value); //等价于popstion+1因为需要包含'\n'; buffer = buffer.Slice(next); //跳过已经读取的数据; } }while (position != null); //指示PipeReader已经消费了多少数据 reader.AdvanceTo(buffer.Start, buffer.End); if (readResult.IsCompleted) { break; } } reader.Complete(); }
public override async Task ListenAsync(CancellationToken token) { while (!token.IsCancellationRequested) { ReadResult result = await _reader.ReadAsync(token); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition? position = PositionOf(buffer.Slice(buffer.GetPosition(1)), _fixVersion); while (position != null && !token.IsCancellationRequested) { ProcessLine(buffer.Slice(0, position.Value)); // Skip to the next message buffer = buffer.Slice(buffer.GetPosition(0, position.Value)); position = PositionOf(buffer.Slice(1), _fixVersion); } _reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { if (buffer.Length > 0) { ProcessLine(buffer); } break; } } _reader.Complete(); CompleteObservers(); token.ThrowIfCancellationRequested(); }
public void PositionOf_ReturnsNullIfNotFound() { ReadOnlySequence <byte> buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3 }); SequencePosition? result = buffer.PositionOf((byte)4); Assert.Null(result); }
public async Task ReadPipeAsync(PipeReader reader, IParserRequestHandler handler) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition?position = null; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var sequence = buffer.Slice(0, position.Value); Logger.Debug("Parsing request..."); Parser.ParseRequestLine(handler, sequence, out var consumed, out var examined); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
/// <summary> /// ReadPipeAsync /// Override this method to process different data protocol. /// </summary> /// <param name="socket"></param> /// <param name="reader"></param> /// <returns></returns> protected virtual async Task ReadPipeAsync(PipeReader reader) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; do { //Abstract SequencePosition?position = buffer.PositionOf((byte)'\n'); if (position == null) { break; } var line = buffer.Slice(0, position.Value); ProcessData(line); var next = buffer.GetPosition(1, position.Value); buffer = buffer.Slice(next); } while (true); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
public void TestSeekIteratorLimitWithinSameBlock(string input, char seek, char limitAfter, int expectedReturnValue) { ReadOnlySequence <byte> originalBuffer = Factory.CreateWithContent(input); SequencePosition scan1 = originalBuffer.Start; ReadOnlySequence <byte> buffer = originalBuffer; // Act SequencePosition?end = originalBuffer.PositionOf((byte)limitAfter); if (end.HasValue) { buffer = originalBuffer.Slice(buffer.Start, buffer.GetPosition(end.Value, 1)); } SequencePosition?returnValue1 = buffer.PositionOf((byte)seek); // Assert Assert.Equal(input.Contains(limitAfter), end.HasValue); if (expectedReturnValue != -1) { int expectedEndIndex = input.IndexOf(seek); Assert.NotNull(returnValue1); Assert.Equal(Encoding.ASCII.GetBytes(input.Substring(expectedEndIndex)), originalBuffer.Slice(returnValue1.Value).ToArray()); } }
private SequencePosition GetNewLinePosition(ReadOnlySequence <byte> buffer, SequencePosition?CRPosition, SequencePosition?LFPosition) { // In case of line ends with LF and no CR in the rest of the buffer. if (!CRPosition.HasValue) { return(LFPosition.Value); } // In case of line ends with CR and no LF in the rest of the buffer. if (!LFPosition.HasValue) { return(CRPosition.Value); } ReadOnlySequence <byte> CRLine = buffer.Slice(0, CRPosition.Value); ReadOnlySequence <byte> LFLine = buffer.Slice(0, LFPosition.Value); // In case of line end with CRLF. if (LFLine.Length - CRLine.Length == 1) { return(LFPosition.Value); } // In case of line ends with LF. if (LFLine.Length < CRLine.Length) { return(LFPosition.Value); } // In case of line ends with Cr. else { return(CRPosition.Value); } }
public void PositionOf_ReturnsNullIfNotFound() { ReadOnlySequence <char> buffer = Factory.CreateWithContent(new char[] { (char)1, (char)2, (char)3 }); SequencePosition? result = buffer.PositionOf((char)4); Assert.Null(result); }
private static int CalculateRecordLength(ReadOnlySequence <byte> span) { // need to figure out how long the header is //var position = span.PositionOf((byte) '\n'); //long lfPos; //if (position == null) //{ // lfPos = span.Length - 1; //} //else //{ // lfPos = position.Value.GetInteger(); //} //while (nextValuePos ) //{ // headerCount++; // var nextPos = span.Slice(nextValuePos).PositionOf((byte)','); // var length = nextPos?.GetInteger() + 1 ?? 0; // nextValuePos += length; // if (length == 0) break; // case for single line csv //} int headerCount = 1; SequencePosition?nextPostion = span.PositionOf((byte)','); while (nextPostion != null) { headerCount++; nextPostion = span.Slice(span.GetPosition(1, nextPostion.Value)).PositionOf((byte)','); } return(headerCount); }
public static async IAsyncEnumerable <MPEGTS.Packet> TryReadPackets(PipeReader pr, [EnumeratorCancellation] CancellationToken cancellationToken = default) { while (!cancellationToken.IsCancellationRequested) { var data = await pr.ReadAsync(cancellationToken); var buf = data.Buffer; SequencePosition?sp = null; foreach (var pkt in ReadPackets(buf, cancellationToken)) { yield return(pkt.packet); sp = pkt.pos; } if (sp != null) { // sp is the start of the last parsed packet // advance to the end of the last parsed packet pr.AdvanceTo(buf.GetPosition(MPEGTS.PacketLength, sp.Value)); } else { pr.AdvanceTo(buf.Start); } //no more data coming if (data.IsCompleted) { break; } } }
public object ManualSplitMemoryT() { var sourceMem = Source.AsMemory(); var readTotal = 0; var len = sourceMem.Length * 4; Span <byte> mem = stackalloc byte[len]; //using (var mem = MemoryPool<byte>.Shared.Rent(len)) //{ var seq = new ReadOnlySequence <char>(sourceMem); SequencePosition?pos = null; while ((pos = seq.PositionOf(CharDot)) != null) { var part = seq.Slice(seq.Start, pos.Value); seq = seq.Slice(seq.GetPosition(1, pos.Value)); // Label memory. var slice = mem.Slice(readTotal); // Write label. var read = Encoding.UTF8.GetBytes(part.First.Span, slice.Slice(1)); // Write label length prefix. slice[0] = (byte)read; readTotal += read + 1; } return(readTotal); //} }
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 IEnumerable <(SequencePosition pos, MPEGTS.Packet packet)> ReadPackets(ReadOnlySequence <byte> buf, CancellationToken cancellationToken = default) { SequencePosition?sp = null; do { sp = buf.PositionOf(MPEGTS.SyncMarker); if (sp != null && buf.Length >= MPEGTS.PacketLength) { //try to parse a packet starting at sp var packetData = buf.Slice(sp.Value, MPEGTS.PacketLength); var pkt = MPEGTS.Packet.Parse(packetData); pkt.OriginalData = packetData; yield return(sp.Value, pkt); var nextMsgPos = buf.GetPosition(MPEGTS.PacketLength, sp.Value); buf = buf.Slice(nextMsgPos); } else { break; } } while (sp != null && !cancellationToken.IsCancellationRequested); }
private bool TryParseJsons(ReadOnlySequence <byte> buffer, out IEnumerable <JsonDocument> jsonDocuments) { var jsons = new List <JsonDocument>(); SequencePosition?firstPosition = null; SequencePosition?lastPosition = null; do { if (buffer.Length <= 0) { break; } firstPosition = GetJsonStartPosition(buffer); lastPosition = GetJsonEndPosition(buffer); if (firstPosition != null && lastPosition != null) { var jsonBuffer = buffer.Slice(firstPosition.Value, lastPosition.Value); if (!TryParseJson(jsonBuffer, out var jsonDocument)) { jsonDocuments = jsons; return(false); } jsons.Add(jsonDocument); buffer = buffer.Slice(lastPosition.Value); } }while (lastPosition != null); jsonDocuments = jsons; return(jsons.Count > 0); }
public static async Task <Person> Deserialize(PipeReader reader) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition? position = null; position = buffer.PositionOf((byte)'"'); buffer = buffer.Slice(position.Value).Slice(1); position = buffer.PositionOf((byte)'"'); var value = buffer.Slice(buffer.Start, position.Value); if (value.Equals(Age)) { position = buffer.PositionOf((byte)' '); buffer = buffer.Slice(position.Value).Slice(1); position = buffer.PositionOf((byte)','); value = buffer.Slice(buffer.Start, position.Value); } else if (value.Equals(Name)) { position = buffer.PositionOf((byte)'"'); buffer = buffer.Slice(position.Value).Slice(1); position = buffer.PositionOf((byte)'"'); value = buffer.Slice(buffer.Start, position.Value); } //pipelineReader.Advance(buffer.End, buffer.End); return(null); }
public void Handle(ref SocketPipelineContext context, ref ReadOnlySequence <byte> data) { using (MemoryStream memoryStream = new MemoryStream()) { using (ICryptoTransform decryptor = this.Crypt.CreateDecryptor()) { using CryptoStream stream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write, leaveOpen: true); byte[] array = data.ToArray(); Base64.DecodeFromUtf8InPlace(array, out int writtenBytes); stream.Write(array, 0, writtenBytes); } ReadOnlySequence <byte> plank = new ReadOnlySequence <byte>(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); //Encryption leaves some ugly null bytes SequencePosition?uglyNulls = plank.PositionOf((byte)'\0'); if (uglyNulls != null) { plank = plank.Slice(start: 0, end: uglyNulls.Value); } context.ProgressHandlerIn(ref plank); } }
protected virtual async Task ProcessCommandLine(Guid clientId, ReadOnlySequence <byte> line) { SequencePosition?position = line.PositionOf((byte)' '); var command = line.Slice(0, position.Value); var data = line.Slice(line.GetPosition(1, position.Value)); //Build command var stringBuilder = new StringBuilder(); foreach (var segment in command) { stringBuilder.Append(Encoding.ASCII.GetString(segment.Span).ToLower()); } var parsedCommand = stringBuilder.ToString(); //Build data stringBuilder.Clear(); foreach (var segment in data) { stringBuilder.Append(Encoding.ASCII.GetString(segment.Span)); } var parsedData = stringBuilder.ToString(); await ProcessMessage(new Message { Service = Enum.Parse(typeof(Service), parsedCommand, true) as Service?, Data = parsedData, ClientId = clientId }); }
public AsyncPipeReaderEnumerator(PipeReader pipeReader, ArrayPool <byte> pool) { _pipeReader = pipeReader; _pool = pool; _current = default; _next = null; }
public void TestSeekByteLimitWithinSameBlock(string input, char seek, int limit, int expectedBytesScanned, int expectedReturnValue) { // Arrange ReadOnlySequence <byte> originalBuffer = Factory.CreateWithContent(input); // Act ReadOnlySequence <byte> buffer = limit > input.Length ? originalBuffer : originalBuffer.Slice(0, limit); SequencePosition?result = buffer.PositionOf((byte)seek); // Assert if (expectedReturnValue == -1) { Assert.Null(result); } else { Assert.NotNull(result); } if (expectedReturnValue != -1) { Assert.Equal(Encoding.ASCII.GetBytes(input.Substring(expectedBytesScanned - 1)), originalBuffer.Slice(result.Value).ToArray()); } }
public void MemorySeek(string raw, char searchFor, int expectIndex) { ReadOnlySequence <byte> cursors = Factory.CreateWithContent(raw); SequencePosition? result = cursors.PositionOf((byte)searchFor); Assert.NotNull(result); Assert.Equal(cursors.Slice(result.Value).ToArray(), Encoding.ASCII.GetBytes(raw.Substring(expectIndex))); }
public void PositionOf_ReturnsPosition(string raw, char searchFor, int expectIndex) { ReadOnlySequence <byte> buffer = Factory.CreateWithContent(raw); SequencePosition? result = buffer.PositionOf((byte)searchFor); Assert.NotNull(result); Assert.Equal(buffer.Slice(result.Value).ToArray(), Encoding.ASCII.GetBytes(raw.Substring(expectIndex))); }
public void PositionOf_ReturnsPosition(string raw, char searchFor, int expectIndex) { ReadOnlySequence <char> buffer = Factory.CreateWithContent(raw.ToCharArray()); SequencePosition? result = buffer.PositionOf((char)searchFor); Assert.NotNull(result); Assert.Equal(buffer.Slice(result.Value).ToArray(), raw.Substring(expectIndex)); }
public static IApplicationBuilder UseHMACHashing(this IApplicationBuilder app) { return(app.UseWhen(context => context.Request.Method == HttpMethods.Post, appBuilder => { appBuilder.Use(async(context, next) => { var reader = context.Request.BodyReader; var bytes = new byte[context.Request.ContentLength.Value]; long destinationIndex = 0; while (true) { ReadResult readResult = await reader.ReadAsync(); var buffer = readResult.Buffer; SequencePosition?position = null; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var readOnlySequence = buffer.Slice(0, position.Value); var tempBytes = readOnlySequence.IsSingleSegment ? readOnlySequence.First.Span.ToArray() : readOnlySequence.ToArray(); Array.Copy(tempBytes, 0, bytes, destinationIndex, tempBytes.Length); destinationIndex = destinationIndex + tempBytes.Length; buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null); if (readResult.IsCompleted && buffer.Length > 0) { var tempBytes = buffer.ToArray(); Array.Copy(tempBytes, 0, bytes, destinationIndex, tempBytes.Length); destinationIndex = destinationIndex + tempBytes.Length; } reader.AdvanceTo(buffer.Start, buffer.End); if (readResult.IsCompleted) { break; } } var txt = System.Text.Encoding.UTF8.GetString(bytes); using (MD5 md5 = MD5.Create()) { var hash = md5.ComputeHash(bytes); context.Items["RequestHash"] = Convert.ToBase64String(hash); } await next(); }); })); }
/// <summary> /// Recycle memory from a previously returned message. /// </summary> private void RecycleLastMessage() { if (this.endOfLastMessage.HasValue) { // A previously returned message can now be safely recycled since the caller wants more. this.ReadData.AdvanceTo(this.endOfLastMessage.Value); this.endOfLastMessage = null; } }
private async Task ReadPipeAsync(PipeReader reader, Action <NmeaMessage> callback, CancellationToken cancellationToken = default) { while (!cancellationToken.IsCancellationRequested) { try { var result = await reader.ReadAsync(cancellationToken).ConfigureAwait(false); var buffer = result.Buffer; SequencePosition?position = null; do { // Look for a EOL in the buffer position = buffer.PositionOf(ByteLF); if (position != null) { // Process the line if (ParseSentence(buffer.Slice(0, position.Value), out var message)) { callback(message); } // Skip the line + the \n character (basically position) buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null && !cancellationToken.IsCancellationRequested); // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.Start, buffer.End); // Stop reading if there's no more data coming if (result.IsCompleted) { _logger.LogTrace("ReadPipeAsync: Writer is Completed"); break; } } catch (OperationCanceledException) { break; } if (AbortAfterUnparsedLines != 0 && _unparsedSequenceLength >= AbortAfterUnparsedLines) { _logger.LogTrace("ReadPipeAsync: Sequntial Unparsed Lines: {0} Limit: {1}", _unparsedSequenceLength, AbortAfterUnparsedLines); _exitReason = ExitReason.TooManySequentialUnparsedLines; break; } } // Mark the PipeReader as complete reader.Complete(); }
private void ParseExtension(ReadOnlyBuffer <byte> buffer, out SequencePosition consumed, out SequencePosition examined) { // Chunk-extensions not currently parsed // Just drain the data consumed = buffer.Start; examined = buffer.Start; do { SequencePosition?extensionCursorPosition = buffer.PositionOf(ByteCR); if (extensionCursorPosition == null) { // End marker not found yet consumed = buffer.End; examined = buffer.End; AddAndCheckConsumedBytes(buffer.Length); return; } ; var extensionCursor = extensionCursorPosition.Value; var charsToByteCRExclusive = buffer.Slice(0, extensionCursor).Length; var sufixBuffer = buffer.Slice(extensionCursor); if (sufixBuffer.Length < 2) { consumed = extensionCursor; examined = buffer.End; AddAndCheckConsumedBytes(charsToByteCRExclusive); return; } sufixBuffer = sufixBuffer.Slice(0, 2); var sufixSpan = sufixBuffer.ToSpan(); if (sufixSpan[1] == '\n') { // We consumed the \r\n at the end of the extension, so switch modes. _mode = _inputLength > 0 ? Mode.Data : Mode.Trailer; consumed = sufixBuffer.End; examined = sufixBuffer.End; AddAndCheckConsumedBytes(charsToByteCRExclusive + 2); } else { // Don't consume suffixSpan[1] in case it is also a \r. buffer = buffer.Slice(charsToByteCRExclusive + 1); consumed = extensionCursor; AddAndCheckConsumedBytes(charsToByteCRExclusive + 1); } } while (_mode == Mode.Extension); }
public void Handle(ref SocketPipelineContext context, ref ReadOnlySequence <byte> data) { SequencePosition?position = data.PositionOf(SplitMessageHandler.BREAK_CHAR); if (position != null) { ReadOnlySequence <byte> withoutTerminator = data.Slice(start: 0, end: position.Value); context.ProgressReadHandler(ref withoutTerminator); data = data.Slice(start: data.GetPosition(1, position.Value)); } }
bool TryReadLine(ref ReadOnlySequence <byte> buffer, out ReadOnlySequence <byte> line) { SequencePosition?position = buffer.PositionOf((byte)'\n'); if (position == null) { line = default; return(false); } line = buffer.Slice(0, position.Value); _reader.AdvanceTo(position.Value); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); return(true); }
protected virtual async ValueTask ProcessLine(Guid clientId, ReadOnlySequence <byte> line) { //ping 200 SequencePosition?position = line.PositionOf((byte)' '); if (!position.HasValue) { await ProcessCommandlessLine(clientId, line); } else { await ProcessCommandLine(clientId, line); } }
protected virtual bool TryReadLine(ref ReadOnlySequence <byte> buffer, out ReadOnlySequence <byte> line) { SequencePosition?position = buffer.PositionOf((byte)'\n'); if (!position.HasValue) { line = default; return(false); } line = buffer.Slice(0, position.Value); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); return(true); }