public void ComparisonMembers_NotEquals() { var position = new SequencePosition(null, 2); var position2 = new SequencePosition(2, 2); Assert.False(position.Equals(position2)); Assert.False(position.Equals((object)position2)); Assert.NotEqual(position.GetHashCode(), position2.GetHashCode()); }
public void ComparisonMembers_IntSegment() { var position = new SequencePosition(2, 2); var position2 = new SequencePosition(2, 2); Assert.True(position.Equals(position2)); Assert.True(position.Equals((object)position2)); Assert.Equal(position.GetHashCode(), position2.GetHashCode()); }
public void ComparisonMembers_NotNullSegment() { var segment = new object(); var position = new SequencePosition(segment, 2); var position2 = new SequencePosition(segment, 2); Assert.True(position == position2); Assert.True(position.Equals(position2)); Assert.True(position.Equals((object)position2)); Assert.False(position != position2); Assert.Equal(position.GetHashCode(), position2.GetHashCode()); }
public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { if (!_isReading) { throw new InvalidOperationException("No reading operation to complete."); } _isReading = false; if (_readCompleted) { // If the old stored _readResult was canceled, it's already been observed. Do not store a canceled read result permanently. _readResult = new ReadResult(_readResult.Buffer.Slice(consumed, _readResult.Buffer.End), isCanceled: false, isCompleted: true); if (!_finalAdvanceCalled && _readResult.Buffer.Length == 0) { _context.Input.AdvanceTo(consumed); _finalAdvanceCalled = true; _context.OnTrailersComplete(); } return; } // If consumed != examined, we cannot reset _context.Input back to a non-reading state after the next call to ReadAsync // simply by calling _context.Input.AdvanceTo(_readResult.Buffer.Start) because the DefaultPipeReader will complain that // "The examined position cannot be less than the previously examined position." _cannotResetInputPipe = !consumed.Equals(examined); _unexaminedInputLength -= TrackConsumedAndExaminedBytes(_readResult, consumed, examined); _context.Input.AdvanceTo(consumed, examined); }
public ReadOnlyMemory <byte> MakeFrame(ReadOnlySequence <byte> seq) { // cached frame if (_lastFrameStart.Equals(seq.Start) && _lastFrameEnd.Equals(seq.End)) { Debug.WriteLine("Hit cached frame"); return(_lastFrame); } _lastFrameStart = seq.Start; _lastFrameEnd = seq.End; if (seq.IsSingleSegment) { Debug.WriteLine("Frame is single segement"); _lastFrame = seq.First; return(seq.First); } Debug.WriteLine("Copy frame data into single Memory"); Memory <byte> ret = new byte[seq.Length]; var ptr = 0; foreach (var mem in seq) { mem.CopyTo(ret.Slice(ptr)); ptr += mem.Length; } _lastFrame = ret; return(ret); }
private static void Byte_MultiSegment(int bufSize, int bufOffset) { var segment1 = new BufferSegment <byte>(new byte[bufSize / 10]); BufferSegment <byte> segment2 = segment1; for (int j = 0; j < 10; j++) { segment2 = segment2.Append(new byte[bufSize / 10]); } var buffer = new ReadOnlySequence <byte>(segment1, bufOffset, segment2, bufSize / 10 - bufOffset); int offset = (int)buffer.Length / 10; SequencePosition end = buffer.GetPosition(0, buffer.End); foreach (BenchmarkIteration iteration in Benchmark.Iterations) { int localInt = 0; using (iteration.StartMeasurement()) { for (int i = 0; i < Benchmark.InnerIterationCount; i++) { SequencePosition pos = buffer.Start; while (!pos.Equals(end)) { pos = buffer.GetPosition(offset, pos); localInt ^= pos.GetInteger(); } } } _volatileInt = localInt; } }
private static void String(int bufSize, int bufOffset) { ReadOnlyMemory <char> memory = new string('a', bufSize).AsMemory(); memory = memory.Slice(bufOffset, bufSize - 2 * bufOffset); var buffer = new ReadOnlySequence <char>(memory); int offset = (int)buffer.Length / 10; SequencePosition end = buffer.GetPosition(0, buffer.End); foreach (BenchmarkIteration iteration in Benchmark.Iterations) { int localInt = 0; using (iteration.StartMeasurement()) { for (int i = 0; i < Benchmark.InnerIterationCount; i++) { SequencePosition pos = buffer.Start; while (!pos.Equals(end)) { pos = buffer.GetPosition(offset, pos); localInt ^= pos.GetInteger(); } } } _volatileInt = localInt; } }
OperationStatus NotEnoughData(TokenType tokenType) { CurrentToken = new Token(tokenType, _reader.SliceToNow(_tokenStart)); _reader.Rewind(_rewindCount); Debug.Assert(_tokenStart.Equals(_reader.Position)); Reset(); return(OperationStatus.NeedMoreData); }
protected long OnAdvance(ReadResult readResult, SequencePosition consumed, SequencePosition examined) { // This code path is fairly hard to understand so let's break it down with an example // ReadAsync returns a ReadResult of length 50. // Advance(25, 40). The examined length would be 40 and consumed length would be 25. // _totalExaminedInPreviousReadResult starts at 0. newlyExamined is 40. // OnDataRead is called with length 40. // _totalExaminedInPreviousReadResult is now 40 - 25 = 15. // The next call to ReadAsync returns 50 again // Advance(5, 5) is called // newlyExamined is 5 - 15, or -10. // Update _totalExaminedInPreviousReadResult to 10 as we consumed 5. // The next call to ReadAsync returns 50 again // _totalExaminedInPreviousReadResult is 10 // Advance(50, 50) is called // newlyExamined = 50 - 10 = 40 // _totalExaminedInPreviousReadResult is now 50 // _totalExaminedInPreviousReadResult is finally 0 after subtracting consumedLength. long examinedLength, consumedLength, totalLength; if (consumed.Equals(examined)) { examinedLength = readResult.Buffer.Slice(readResult.Buffer.Start, examined).Length; consumedLength = examinedLength; } else { consumedLength = readResult.Buffer.Slice(readResult.Buffer.Start, consumed).Length; examinedLength = consumedLength + readResult.Buffer.Slice(consumed, examined).Length; } if (examined.Equals(readResult.Buffer.End)) { totalLength = examinedLength; } else { totalLength = readResult.Buffer.Length; } var newlyExamined = examinedLength - _examinedUnconsumedBytes; if (newlyExamined > 0) { OnDataRead(newlyExamined); _examinedUnconsumedBytes += newlyExamined; } _examinedUnconsumedBytes -= consumedLength; _alreadyTimedBytes = totalLength - consumedLength; return(newlyExamined); }
public async Task ThrowingFromStreamCallsAdvanceToWithStartOfLastReadResult(int throwAfterNWrites) { var wrappedPipeReader = new TestPipeReader(PipeReader); var stream = new ThrowAfterNWritesStream(throwAfterNWrites); Task task = wrappedPipeReader.CopyToAsync(stream); Pipe.Writer.WriteEmpty(10); await Pipe.Writer.FlushAsync(); // Write twice for the test case where the stream throws on the second write. Pipe.Writer.WriteEmpty(10); await Pipe.Writer.FlushAsync(); await Assert.ThrowsAsync <InvalidOperationException>(() => task); SequencePosition startPosition = wrappedPipeReader.LastReadResult.Buffer.Start; Assert.NotNull(startPosition.GetObject()); Assert.True(startPosition.Equals(wrappedPipeReader.LastConsumed)); Assert.True(startPosition.Equals(wrappedPipeReader.LastExamined)); }
/// <inheritdoc /> public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { ThrowIfCompleted(); // Fast path: did we consume everything? if (consumed.Equals(_sequence.End)) { _sequence = ReadOnlySequence <byte> .Empty; return; } _sequence = _sequence.Slice(consumed); }
protected async Task ReadPipeAsync(PipeReader reader) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (result.IsCanceled) { break; } var completed = result.IsCompleted; while (true) { var package = ReaderBuffer(buffer, out consumed, out examined); if (package != null) { await OnPackageReceived(package); } if (examined.Equals(buffer.End)) { break; } buffer = buffer.Slice(examined); } if (completed) { break; } } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { if (!_isReading) { throw new InvalidOperationException("No reading operation to complete."); } _isReading = false; // The current body is read, though there might be more bytes to read on the stream with pipelining if (_readCompleted) { if (!_finalAdvanceCalled && consumed.Equals(_readResult.Buffer.End)) { // Don't reference the old buffer as it will be released by the pipe afer calling AdvancedTo _readResult = new ReadResult(new ReadOnlySequence <byte>(), isCanceled: false, isCompleted: true); _context.Input.AdvanceTo(consumed); _finalAdvanceCalled = true; _context.OnTrailersComplete(); } else { // If the old stored _readResult was canceled, it's already been observed. Do not store a canceled read result permanently. _readResult = new ReadResult(_readResult.Buffer.Slice(consumed, _readResult.Buffer.End), isCanceled: false, isCompleted: true); } return; } // If consumed != examined, we cannot reset _context.Input back to a non-reading state after the next call to ReadAsync // simply by calling _context.Input.AdvanceTo(_readResult.Buffer.Start) because the DefaultPipeReader will complain that // "The examined position cannot be less than the previously examined position." _cannotResetInputPipe = !consumed.Equals(examined); _unexaminedInputLength -= TrackConsumedAndExaminedBytes(_readResult, consumed, examined); _context.Input.AdvanceTo(consumed, examined); }
private int IterateGetPosition(ReadOnlySequence <T> sequence) { int consume = 0; SequencePosition position = sequence.Start; int offset = (int)(sequence.Length / 10); SequencePosition end = sequence.GetPosition(0, sequence.End); while (!position.Equals(end)) { position = sequence.GetPosition(offset, position); consume += position.GetInteger(); } return(consume); }
public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) { // This code path is fairly hard to understand so let's break it down with an example // ReadAsync returns a ReadResult of length 50. // Advance(25, 40). The examined length would be 40 and consumed length would be 25. // _totalExaminedInPreviousReadResult starts at 0. newlyExamined is 40. // OnDataRead is called with length 40. // _totalExaminedInPreviousReadResult is now 40 - 25 = 15. // The next call to ReadAsync returns 50 again // Advance(5, 5) is called // newlyExamined is 5 - 15, or -10. // Update _totalExaminedInPreviousReadResult to 10 as we consumed 5. // The next call to ReadAsync returns 50 again // _totalExaminedInPreviousReadResult is 10 // Advance(50, 50) is called // newlyExamined = 50 - 10 = 40 // _totalExaminedInPreviousReadResult is now 50 // _totalExaminedInPreviousReadResult is finally 0 after subtracting consumedLength. long examinedLength; long consumedLength; if (consumed.Equals(examined)) { examinedLength = _readResult.Buffer.Slice(_readResult.Buffer.Start, examined).Length; consumedLength = examinedLength; } else { consumedLength = _readResult.Buffer.Slice(_readResult.Buffer.Start, consumed).Length; examinedLength = consumedLength + _readResult.Buffer.Slice(consumed, examined).Length; } _context.RequestBodyPipe.Reader.AdvanceTo(consumed, examined); var newlyExamined = examinedLength - _alreadyExaminedInNextReadResult; if (newlyExamined > 0) { OnDataRead(newlyExamined); _alreadyExaminedInNextReadResult += newlyExamined; } _alreadyExaminedInNextReadResult -= consumedLength; }
public async IAsyncEnumerable <object> Read() { ReadResult result; do { result = await reader.ReadAsync(); var buffer = result.Buffer; object? item; SequencePosition finalPosition = buffer.Start; do { (item, finalPosition) = FirstObjectFromBuffer(buffer.Slice(finalPosition)); if (item != null) { yield return(item); } } while (item != null && !finalPosition.Equals(buffer.End)); reader.AdvanceTo(finalPosition, buffer.End); } while (!(result.IsCompleted || result.IsCanceled)); }
protected async Task ReadPipeAsync(PipeReader reader) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (result.IsCompleted) { break; } while (true) { ReaderBuffer(buffer, out consumed, out examined); if (examined.Equals(buffer.End)) { break; } buffer = buffer.Slice(examined); } } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
private static void Byte_Array(int bufSize, int bufOffset) { var buffer = new ReadOnlySequence <byte>(new byte[bufSize], bufOffset, bufSize - 2 * bufOffset); int offset = (int)buffer.Length / 10; SequencePosition end = buffer.GetPosition(0, buffer.End); foreach (BenchmarkIteration iteration in Benchmark.Iterations) { int localInt = 0; using (iteration.StartMeasurement()) { for (int i = 0; i < Benchmark.InnerIterationCount; i++) { SequencePosition pos = buffer.Start; while (!pos.Equals(end)) { pos = buffer.GetPosition(offset, pos); localInt ^= pos.GetInteger(); } } } _volatileInt = localInt; } }
protected async Task ReadPipeAsync(PipeReader reader) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (result.IsCanceled) { break; } var completed = result.IsCompleted; while (true) { var package = ReaderBuffer(buffer, out consumed, out examined); if (package != null) { await OnPackageReceived(package); } var maxPackageLength = Options.MaxPackageLength; if (maxPackageLength > 0 && buffer.Length > maxPackageLength) { Logger.LogError($"Package cannot be larger than {maxPackageLength}."); completed = true; // close the the connection directly Close(); break; } if (examined.Equals(buffer.End)) { break; } buffer = buffer.Slice(examined); } if (completed) { break; } } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }