| File: System\Net\Quic\Internal\ReceiveBuffers.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Quic\src\System.Net.Quic.csproj (System.Net.Quic) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Quic; namespace System.Net.Quic; internal struct ReceiveBuffers { private const int MaxBufferedBytes = 64 * 1024; private readonly object _syncRoot; private MultiArrayBuffer _buffer; private bool _final; public ReceiveBuffers() { _syncRoot = new object(); _buffer = default; _final = default; } public void SetFinal() { lock (_syncRoot) { _final = true; } } public bool HasCapacity() { lock (_syncRoot) { return _buffer.ActiveMemory.Length < MaxBufferedBytes; } } public int CopyFrom(ReadOnlySpan<QUIC_BUFFER> quicBuffers, int totalLength, bool final) { lock (_syncRoot) { if (_buffer.ActiveMemory.Length > MaxBufferedBytes - totalLength) { totalLength = MaxBufferedBytes - _buffer.ActiveMemory.Length; final = false; } _final = final; _buffer.EnsureAvailableSpace(totalLength); int totalCopied = 0; for (int i = 0; i < quicBuffers.Length; ++i) { Span<byte> quicBuffer = quicBuffers[i].Span; if (totalLength < quicBuffer.Length) { quicBuffer = quicBuffer.Slice(0, totalLength); } _buffer.AvailableMemory.CopyFrom(quicBuffer); _buffer.Commit(quicBuffer.Length); totalCopied += quicBuffer.Length; totalLength -= quicBuffer.Length; } return totalCopied; } } public int CopyTo(Memory<byte> buffer, out bool completed, out bool empty) { lock (_syncRoot) { int copied = 0; if (!_buffer.IsEmpty) { MultiMemory activeBuffer = _buffer.ActiveMemory; copied = Math.Min(buffer.Length, activeBuffer.Length); activeBuffer.Slice(0, copied).CopyTo(buffer.Span); _buffer.Discard(copied); } completed = _buffer.IsEmpty && _final; empty = _buffer.IsEmpty; return copied; } } }