public override byte[] ToByteArray()
{
if (this._finalBytes != null)
return this._finalBytes;
if (this.HeaderBytes == null)
this.HeaderBytes = PublicHeader(QuicClient.QUIC_VERSION, this.ConnectionId, this._packetNumber);
for (var i = 0; i < this._frames.Count; i++)
{
var key = this._frames.Keys.ElementAt(i);
this._frames[key] = this._frames[key] ?? key.ToByteArray();
}
var frameByteArrays = this._frames.Select(f => f.Value).ToArray();
var frameByteCount = frameByteArrays.Sum(f => f.Length);
var bytes = new byte[this.HeaderBytes.Length + 12 + (this.FecGroup == null ? 1 : 2) + frameByteCount];
// Apply public header
Array.Copy(this.HeaderBytes, 0, bytes, 0, this.HeaderBytes.Length);
var next = this.HeaderBytes.Length;
// Apply message authentication hash (only for null-encrypted)
if (this.MessageAuthenticationHash != null)
Array.Copy(this.MessageAuthenticationHash, 0, bytes, next, 12);
next += 12;
// Apply private header
if (this.FecGroup == null)
next++;
else
{
bytes[next] ^= PRIVATE_FLAG_FEC_GROUP;
bytes[next + 1] = this.FecGroup.Value;
next += 2;
}
// Add frames
foreach (var fba in frameByteArrays)
{
Array.Copy(fba, 0, bytes, next, fba.Length);
next += fba.Length;
}
return bytes;
}
}