public override TPackageInfo Filter(ref SequenceReader <byte> reader) { if (!_foundBeginMark) { var beginMark = _beginMark.Span; for (var i = 0; i < beginMark.Length - 1; i++) { if (!reader.IsNext(beginMark, advancePast: true)) { throw new ProtocolException("Invalid beginning part of the package."); } } _foundBeginMark = true; } var endMark = _endMark.Span; if (!reader.TryReadToAny(out ReadOnlySequence <byte> pack, endMark, advancePastDelimiter: false)) { return(null); } for (var i = 0; i < endMark.Length - 1; i++) { if (!reader.IsNext(endMark, advancePast: true)) { return(null); } } return(DecodePackage(pack)); }
public static ServerFullStateResponse ParseFullState(RawResponse rawResponse) { if (rawResponse.RawData.Length <= 5) { throw new IncorrectPackageDataException(rawResponse.RawData); } var reader = new SequenceReader <byte>(new ReadOnlySequence <byte>(rawResponse.RawData)); reader.Advance(1); // Skip Type var sessionId = ParseSessionId(ref reader); if (!reader.IsNext(constant1, advancePast: true)) { throw new IncorrectPackageDataException(rawResponse.RawData); } var statusKeyValues = new Dictionary <string, string>(); while (!reader.IsNext(0, advancePast: true)) { var key = ReadString(ref reader); var value = ReadString(ref reader); statusKeyValues.Add(key, value); } if (!reader.IsNext(constant2, advancePast: true)) // Padding: 10 bytes constant { throw new IncorrectPackageDataException(rawResponse.RawData); } var players = new List <string>(); while (!reader.IsNext(0, advancePast: true)) { players.Add(ReadString(ref reader)); } ServerFullStateResponse fullState = new ( serverUUID : rawResponse.ServerUUID, sessionId : sessionId, motd : statusKeyValues["hostname"], gameType : statusKeyValues["gametype"], gameId : statusKeyValues["game_id"], version : statusKeyValues["version"], plugins : statusKeyValues["plugins"], map : statusKeyValues["map"], numPlayers : int.Parse(statusKeyValues["numplayers"]), maxPlayers : int.Parse(statusKeyValues["maxplayers"]), playerList : players.ToArray(), hostIp : statusKeyValues["hostip"], hostPort : int.Parse(statusKeyValues["hostport"]), rawData : (byte[])rawResponse.RawData.Clone() ); return(fullState); }
public void IsNext_Empty(bool advancePast) { var reader = new SequenceReader <char>(ReadOnlySequence <char> .Empty); Assert.False(reader.IsNext('Z', advancePast)); Assert.Equal(0, reader.Consumed); // Nothing is always next Assert.True(reader.IsNext(ReadOnlySpan <char> .Empty, advancePast)); Assert.Equal(0, reader.Consumed); // Something isn't Assert.False(reader.IsNext(new char[] { '\0' }, advancePast)); Assert.Equal(0, reader.Consumed); }
public WebSocketPackage Filter(ref SequenceReader <byte> reader) { var terminatorSpan = _headerTerminator.Span; if (!reader.TryReadToAny(out ReadOnlySequence <byte> pack, terminatorSpan, advancePastDelimiter: false)) { return(null); } for (var i = 0; i < terminatorSpan.Length - 1; i++) { if (!reader.IsNext(terminatorSpan, advancePast: true)) { return(null); } } var header = ParseHttpHeaderItems(pack); var package = new WebSocketPackage { HttpHeader = header, OpCode = OpCode.Handshake }; NextFilter = new WebSocketDataPipelineFilter(); return(package); }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, JT808TcpSession session, out SequencePosition consumed) { SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { byte[] data = null; try { data = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).ToArray(); //过滤掉不是808标准包(14) //(头)1+(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1+(尾)1 if (data != null && data.Length > 14) { var package = Serializer.HeaderDeserialize(data); if (BlacklistManager.Contains(package.Header.TerminalPhoneNo)) { if (Logger.IsEnabled(LogLevel.Warning)) { Logger.LogWarning($"[Blacklist {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()}"); } session.ReceiveTimeout.Cancel(); break; } # if DEBUG Interlocked.Increment(ref MessageReceiveCounter); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()},Counter:{MessageReceiveCounter}"); } #else if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()}"); } #endif SessionManager.TryLink(package.Header.TerminalPhoneNo, session); Processor(session, package); } }
Token <TNumber> LexCompoundOperator() { reader.TryRead(out var c); if (reader.IsNext('=')) { reader.Advance(1); return(new Token <TNumber>(c switch { '+' => SyntaxKind.PlusEquals, '-' => SyntaxKind.MinusEquals, '*' => SyntaxKind.AsteriskEquals, '/' => SyntaxKind.SlashEquals }));
public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state) { if (reader.IsNext(RasterEndToken.Span)) { reader.Advance(RasterEndToken.Length); return(ReaderState.Done, null); } else { return(ReaderState.RasterRow, null); } }
internal override bool TryMatchInternal(PartialExecutionData data, ref SequenceReader <byte> reader, out OperationStatus status) { if (reader.Remaining < Match.Length) { return(DoneWith(status = OperationStatus.NeedMoreData)); } if (!reader.IsNext(Match.Span)) { return(DoneWith(status = OperationStatus.InvalidData)); } data.AddData(this, ref reader, Match.Length); return(DoneWith(status = OperationStatus.Done)); }
public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state) { if (reader.IsNext(TextSegmentEndToken.Span)) { reader.Advance(TextSegmentEndToken.Length); this.FlushEntry(state); return(ReaderState.BitDepth, null); } if (reader.TryReadTo(out ReadOnlySequence <byte> text, TextEntryEndToken.Span)) { // TODO: Use SequenceReader to extract segments? string line = Encoding.ASCII.GetString(text); if (line.Length > 0) { if (line[0] == '!') { this.StartEntry("!", line.Substring(1), state); } else if (line.StartsWith(" ")) { this.lines.Add(line.Substring(4)); } else { int index = line.IndexOf('/'); if (index >= 0) { this.StartEntry(line.Substring(0, index), line.Substring(index + 1), state); } else { this.StartEntry("?", line, state); } } } return(null, true); } else { return(null, false); } }
public void RewindEmptyFirstSpan() { // This is to hit the "if (memory.Length == 0)" branch in ResetReader. ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] { new byte[0], new byte[] { 1, 2 }, new byte[] { 3, 4 } }); var reader = new SequenceReader <byte>(bytes); reader.Advance(3); Assert.True(reader.IsNext(4)); reader.Rewind(2); Assert.Equal(new byte[] { 1, 2 }, reader.CurrentSpan.ToArray()); }
public override TPackageInfo Filter(ref SequenceReader <byte> reader) { var terminator = new ReadOnlySpan <byte>(_terminator); if (!reader.TryReadToAny(out ReadOnlySpan <byte> pack, terminator, advancePastDelimiter: false)) { return(null); } for (var i = 0; i < _terminator.Length - 1; i++) { if (!reader.IsNext(_terminator, advancePast: true)) { return(null); } } return(ResolvePackage(pack)); }
public void IsNext_Value() { ReadOnlySequence <char> chars = SequenceFactory.Create(new char[][] { new char[] { 'A' }, new char[] { 'B', 'C' }, }); var reader = new SequenceReader <char>(chars); Assert.False(reader.IsNext('Z', advancePast: false)); Assert.False(reader.IsNext('B', advancePast: false)); Assert.True(reader.IsNext('A', advancePast: false)); Assert.True(reader.IsNext('A', advancePast: true)); Assert.True(reader.IsNext('B', advancePast: true)); Assert.True(reader.IsNext('C', advancePast: true)); Assert.False(reader.IsNext('C', advancePast: true)); Assert.True(reader.End); }
public override TPackageInfo Filter(ref SequenceReader <byte> reader) { var terminator = _terminator; var terminatorSpan = terminator.Span; if (!reader.TryReadToAny(out ReadOnlySequence <byte> pack, terminatorSpan, advancePastDelimiter: false)) { return(null); } for (var i = 0; i < _terminator.Length - 1; i++) { if (!reader.IsNext(terminatorSpan, advancePast: true)) { return(null); } } return(DecodePackage(pack)); }
public override TPackageInfo Filter(ref SequenceReader <byte> reader) { if (reader.Length == 6) // 检测设备接入(初次连接后发送mac),有人USR-W610初次连接会发送6个字节的mac地址 { var mac = reader.Sequence.Slice(reader.CurrentSpanIndex, 6); string macStr = string.Empty; mac.ToArray().ToList().ForEach(b => { macStr += b.ToString("X2").ToUpper(); }); DeviceRegister?.Invoke(macStr); } if (!_foundBeginMark) { var beginMark = _beginMark.Span; while (!reader.IsNext(beginMark, advancePast: false)) { if (reader.CurrentSpanIndex == reader.Length) { return(null); } reader.Advance(1); } _foundBeginMark = true; } if (reader.Remaining < _fixedSize) { return(null); } var pack = reader.Sequence.Slice(reader.CurrentSpanIndex, _fixedSize); reader.Advance(_fixedSize); return(DecodePackage(ref pack)); }
public void Test2() { var reader = new ReadOnlySequence <byte>(new byte[] { 0x7E, 0, 1, 2, 0x7E, 0x7E, 0, 1, 0x7E, 0x7E, 2, 2, 2 }); SequenceReader <byte> seqReader = new SequenceReader <byte>(reader); int index = 0; byte mark = 0; long totalConsumed = 0; List <byte[]> packages = new List <byte[]>(); while (!seqReader.End) { if (seqReader.IsNext(0x7E, advancePast: true)) { if (mark == 1) { var package = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).ToArray(); packages.Add(package); totalConsumed += (seqReader.Consumed - totalConsumed); index++; if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } index++; } Assert.Equal(13, index); Assert.Equal(2, packages.Count); Assert.Equal(9, totalConsumed); Assert.Equal(13, seqReader.Consumed); }
public static void ReadLines(ReadOnlySequence <byte> sequence) { var reader = new SequenceReader <byte>(sequence); while (!reader.End) { if (!reader.TryReadToAny(out ReadOnlySpan <byte> line, CRLF, advancePastDelimiter: false)) { // Couldn't find another delimiter // ... } if (!reader.IsNext(CRLF, advancePast: true)) { // Not a good CR/LF pair // ... } // line is valid, process ProcessLine(line); } }
public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state) { if (reader.IsNext(RasterEndToken.Span)) { reader.Advance(RasterEndToken.Length); if (!this.rowNumber.HasValue) { throw new InvalidOperationException("A raster row should start with a row number."); } state.RowEntries.Add(this.rowNumber.Value, this.entries.ToArray()); return(ReaderState.RasterSegment, null); } if (reader.TryReadVariableLengthValue(out ReadOnlySequence <byte> values)) { if (this.rowNumber == null) { this.rowNumber = ParseRasterRowNumber(values); } else { if (!state.BitDepth.HasValue) { throw new InvalidOperationException("Bit depth must be parsed before the raster segment."); } this.entries.Add(ParseRasterRun(values, state.BitDepth.Value)); } return(null, true); } else { return(null, false); } }
public WebSocketPackage Filter(ref SequenceReader <byte> reader) { var terminatorSpan = _headerTerminator.Span; if (!reader.TryReadToAny(out ReadOnlySequence <byte> pack, terminatorSpan, advancePastDelimiter: false)) { return(null); } for (var i = 0; i < terminatorSpan.Length - 1; i++) { if (!reader.IsNext(terminatorSpan, advancePast: true)) { return(null); } } //var headerItems = ParseHttpHeaderItems(pack); //var secWebSocketVersion = headerItems[WebSocketConstant.SecWebSocketVersion]; //var secWebSocketKey = headerItems[WebSocketConstant.SecWebSocketKey]; return(null); }
public bool IsNext(ReadOnlyByteSpan next, bool advancePast = false) => Data.IsNext(next, advancePast);
public bool Parse(ref SequenceReader <char> sequenceReader, ref List <object> parameters) => sequenceReader.IsNext(_literal.AsSpan(), true);
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, UnionTcpSession session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { ReadOnlySpan <byte> contentSpan = ReadOnlySpan <byte> .Empty; try { contentSpan = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).FirstSpan; //过滤掉不是808标准包(14) //(头)1+(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1+(尾)1 if (contentSpan.Length > 14) { var package = Serializer.HeaderDeserialize(contentSpan, minBufferSize: 10240); AtomicCounterService.MsgSuccessIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Success Counter]:{AtomicCounterService.MsgSuccessCount}"); } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); } SessionManager.TryLink(package.Header.TerminalPhoneNo, session); _unionNormalReplyMessageHandler.Processor(package, session); } } catch (NotImplementedException ex) { Logger.LogError(ex.Message); } catch (JT808Exception ex) { AtomicCounterService.MsgFailIncrement(); if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); } Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{contentSpan.ToArray().ToHexString()}"); } totalConsumed += (seqReader.Consumed - totalConsumed); if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } } if (seqReader.Length == totalConsumed) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }
// For multi-segment parsing of a read only sequence private void ParseValuesSlow( ref ReadOnlySequence <byte> buffer, ref KeyValueAccumulator accumulator, bool isFinalBlock) { var sequenceReader = new SequenceReader <byte>(buffer); var consumed = sequenceReader.Position; var equalsDelimiter = GetEqualsForEncoding(); var andDelimiter = GetAndForEncoding(); while (!sequenceReader.End) { // TODO seems there is a bug with TryReadTo (advancePastDelimiter: true). It isn't advancing past the delimiter on second read. if (!sequenceReader.TryReadTo(out ReadOnlySequence <byte> key, equalsDelimiter, advancePastDelimiter: false) || !sequenceReader.IsNext(equalsDelimiter, true)) { if (sequenceReader.Consumed > KeyLengthLimit) { ThrowKeyTooLargeException(); } break; } if (key.Length > KeyLengthLimit) { ThrowKeyTooLargeException(); } if (!sequenceReader.TryReadTo(out ReadOnlySequence <byte> value, andDelimiter, false) || !sequenceReader.IsNext(andDelimiter, true)) { if (!isFinalBlock) { if (sequenceReader.Consumed - key.Length > ValueLengthLimit) { ThrowValueTooLargeException(); } break; } value = buffer.Slice(sequenceReader.Position); sequenceReader.Advance(value.Length); } if (value.Length > ValueLengthLimit) { ThrowValueTooLargeException(); } // Need to call ToArray if the key/value spans multiple segments var decodedKey = GetDecodedStringFromReadOnlySequence(key); var decodedValue = GetDecodedStringFromReadOnlySequence(value); AppendAndVerify(ref accumulator, decodedKey, decodedValue); consumed = sequenceReader.Position; } buffer = buffer.Slice(consumed); }
public void TryReadTo_SkipDelimiter_Runs() { ReadOnlySequence <byte> bytes = SequenceFactory.CreateUtf8("abc^^|def"); SequenceReader <byte> reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out ReadOnlySpan <byte> span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); // Split after escape char bytes = SequenceFactory.CreateUtf8("abc^^", "|def"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); // Split before and after escape char bytes = SequenceFactory.CreateUtf8("abc^", "^", "|def"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(5, reader.Consumed); // Check advance past delimiter reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray()); Assert.True(reader.IsNext((byte)'d')); Assert.Equal(6, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'d')); Assert.Equal(6, reader.Consumed); // Leading run of 2 bytes = SequenceFactory.CreateUtf8("^^|abc"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("^^"), span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(2, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(Encoding.UTF8.GetBytes("^^"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(2, reader.Consumed); // Leading run of 3 bytes = SequenceFactory.CreateUtf8("^^^|abc"); reader = new SequenceReader <byte>(bytes); Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'^')); Assert.Equal(0, reader.Consumed); Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'^')); Assert.Equal(0, reader.Consumed); // Trailing run of 3 bytes = SequenceFactory.CreateUtf8("abc^^^|"); reader = new SequenceReader <byte>(bytes); Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'a')); Assert.Equal(0, reader.Consumed); Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'a')); Assert.Equal(0, reader.Consumed); // Trailing run of 3, split bytes = SequenceFactory.CreateUtf8("abc^^^", "|"); reader = new SequenceReader <byte>(bytes); Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'a')); Assert.Equal(0, reader.Consumed); Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.True(reader.IsNext((byte)'a')); Assert.Equal(0, reader.Consumed); }
public void TryReadTo_SkipDelimiter() { byte[] expected = Encoding.UTF8.GetBytes("This is our ^|understanding^|"); ReadOnlySequence <byte> bytes = SequenceFactory.CreateUtf8("This is our ^|understanding^|| you see."); SequenceReader <byte> reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out ReadOnlySpan <byte> span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); // Put the skip delimiter in another segment bytes = SequenceFactory.CreateUtf8("This is our ^|understanding", "^|| you see."); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); // Put the skip delimiter at the end of the segment bytes = SequenceFactory.CreateUtf8("This is our ^|understanding^", "|| you see."); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)' ')); Assert.Equal(30, reader.Consumed); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); // No trailing data bytes = SequenceFactory.CreateUtf8("This is our ^|understanding^||"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.IsNext((byte)'|')); Assert.Equal(29, reader.Consumed); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, span.ToArray()); Assert.True(reader.End); Assert.Equal(30, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(expected, sequence.ToArray()); Assert.True(reader.End); Assert.Equal(30, reader.Consumed); // All delimiters skipped bytes = SequenceFactory.CreateUtf8("This is our ^|understanding^|"); reader = new SequenceReader <byte>(bytes); Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(0, reader.Consumed); Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false)); Assert.Equal(0, reader.Consumed); reader = new SequenceReader <byte>(bytes); Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(0, reader.Consumed); Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(0, reader.Consumed); bytes = SequenceFactory.CreateUtf8("abc^|de|"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("abc^|de"), span.ToArray()); Assert.True(reader.End); Assert.Equal(8, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("abc^|de"), sequence.ToArray()); Assert.True(reader.End); Assert.Equal(8, reader.Consumed); // Escape leads bytes = SequenceFactory.CreateUtf8("^|a|b"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("^|a"), span.ToArray()); Assert.True(reader.IsNext((byte)'b')); Assert.Equal(4, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("^|a"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'b')); Assert.Equal(4, reader.Consumed); // Delimiter starts second segment. bytes = SequenceFactory.CreateUtf8("^", "|a|b"); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("^|a"), span.ToArray()); Assert.True(reader.IsNext((byte)'b')); Assert.Equal(4, reader.Consumed); reader.Rewind(reader.Consumed); Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true)); Assert.Equal(Encoding.UTF8.GetBytes("^|a"), sequence.ToArray()); Assert.True(reader.IsNext((byte)'b')); Assert.Equal(4, reader.Consumed); }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, Socket session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { try { var data = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).ToArray(); var package = JT808Serializer.Deserialize(data, minBufferSize: 8096); if (producer != null) { producer.ProduceAsync(package); } ReceiveAtomicCounterService.MsgSuccessIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Success Counter]:{ReceiveAtomicCounterService.MsgSuccessCount}"); } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.RemoteEndPoint}]:{data.ToHexString()}"); } } catch (JT808Exception ex) { Logger.LogError(ex, $"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode}"); } totalConsumed += (seqReader.Consumed - totalConsumed); if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } } if (seqReader.Length == totalConsumed) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, JT808TcpSession session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { try { var package = Serializer.HeaderDeserialize(seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).FirstSpan); AtomicCounterService.MsgSuccessIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Success Counter]:{AtomicCounterService.MsgSuccessCount}"); } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); } //设直连模式和转发模式的会话如何处理 SessionManager.TryLink(package.Header.TerminalPhoneNo, session); if (Configuration.MessageQueueType == JT808MessageQueueType.InMemory) { MsgProducer.ProduceAsync(session.SessionID, package.OriginalData.ToArray()); } else { MsgProducer.ProduceAsync(package.Header.TerminalPhoneNo, package.OriginalData.ToArray()); } } catch (JT808Exception ex) { AtomicCounterService.MsgFailIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); } Logger.LogError(ex, $"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode}"); } totalConsumed += (seqReader.Consumed - totalConsumed); if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } } if (seqReader.Length == totalConsumed) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }
public void IsNext_Span() { ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] { new byte[] { 0 }, new byte[] { 1, 2 }, new byte[] { 3, 4 }, new byte[] { 5, 6, 7, 8 } }); var reader = new SequenceReader <byte>(bytes); Assert.True(reader.IsNext(ReadOnlySpan <byte> .Empty, advancePast: false)); Assert.True(reader.IsNext(ReadOnlySpan <byte> .Empty, advancePast: true)); Assert.True(reader.IsNext(new byte[] { 0 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 2 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 2 }, advancePast: true)); Assert.True(reader.IsNext(new byte[] { 0, 1 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 1, 3 }, advancePast: false)); Assert.True(reader.IsNext(new byte[] { 0, 1, 2 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 4 }, advancePast: false)); Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3 }, advancePast: false)); Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4 }, advancePast: false)); Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5 }, advancePast: false)); Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, advancePast: false)); Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, advancePast: true)); Assert.Equal(0, reader.Consumed); Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3 }, advancePast: true)); Assert.True(reader.IsNext(new byte[] { 4, 5, 6 }, advancePast: true)); Assert.True(reader.TryPeek(out byte value)); Assert.Equal(7, value); Assert.True(reader.IsNext(new byte[] { 7, 8 }, advancePast: true)); Assert.True(reader.End); }