public async Task <Packets.RegularPacket> CutNextPacketAsync() { if (!this._connectionid.HasValue) { throw new InvalidOperationException("Connection ID is not established!"); } if (this.Count == 0) { return(null); } uint remaining = Packets.AbstractPacketBase.MTU; ulong packetNumber; lock (this._packetNumberLock) { this._packetNumber++; packetNumber = this._packetNumber; } var regular = new Packets.RegularPacket(this._connectionid.Value, packetNumber, null); // TODO: FEC GROUP's. remaining -= regular.GetHeaderLength(); MultiplexedTransfer nextTransfer; long assignedDataSize; bool fin; StreamFrame streamFrame; lock (this._dequeueLock) { MultiplexedTransfer peekedTransfer; do { if (!this.TryPeek(out peekedTransfer)) { return(null); // My queue is _now_ empty, just say nothing to do. } // Prototype our stream frame var streamRemainingByteCount = peekedTransfer.Stream.Length - peekedTransfer.Stream.Position; streamFrame = new StreamFrame(peekedTransfer.StreamId, Convert.ToUInt64(peekedTransfer.Stream.Position)); var prototypeLength = streamFrame.GetMetadataLength(); assignedDataSize = Math.Min(remaining, prototypeLength); var transferDone = assignedDataSize == streamRemainingByteCount; fin = transferDone && peekedTransfer.TerminateStream; if (!this.TryDequeue(out nextTransfer)) { return(null); // My queue is _now_ empty, just say nothing to do. } if (nextTransfer.TransferId != peekedTransfer.TransferId) { this.Enqueue(nextTransfer); // Whoops, something changed outside of our lock... so, redo our calculations. } }while (nextTransfer.TransferId != peekedTransfer.TransferId); } try { // Hydrate our stream frame prototype var streamData = new byte[assignedDataSize]; await nextTransfer.Stream.ReadAsync(streamData, (int)nextTransfer.Stream.Position, streamData.Length); streamFrame.SetData(streamData, fin); } catch (Exception) { // Something went wrong. Requeue the transfer. this.Enqueue(nextTransfer); throw; } return(regular); }