EonaCat.Network/EonaCat.Network/System/Quic/Infrastructure/Packets/LongHeaderPacket.cs

99 lines
3.0 KiB
C#

using EonaCat.Quic.Helpers;
using System.Collections.Generic;
namespace EonaCat.Quic.Infrastructure.Packets
{
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
public class LongHeaderPacket : Packet
{
public override byte Type => 0b1100_0000; // 1100 0000
public byte DestinationConnectionIdLength { get; set; }
public IntegerParts DestinationConnectionId { get; set; }
public byte SourceConnectionIdLength { get; set; }
public IntegerParts SourceConnectionId { get; set; }
public PacketType PacketType { get; set; }
public LongHeaderPacket()
{
}
public LongHeaderPacket(PacketType packetType, IntegerParts destinationConnectionId, IntegerParts sourceConnectionId)
{
PacketType = packetType;
DestinationConnectionIdLength = destinationConnectionId.Size;
DestinationConnectionId = destinationConnectionId;
SourceConnectionIdLength = sourceConnectionId.Size;
SourceConnectionId = sourceConnectionId;
}
public override void Decode(byte[] packet)
{
ByteArray array = new ByteArray(packet);
byte type = array.ReadByte();
PacketType = DecodeTypeFiled(type);
Version = array.ReadUInt32();
DestinationConnectionIdLength = array.ReadByte();
if (DestinationConnectionIdLength > 0)
{
DestinationConnectionId = array.ReadGranularInteger(DestinationConnectionIdLength);
}
SourceConnectionIdLength = array.ReadByte();
if (SourceConnectionIdLength > 0)
{
SourceConnectionId = array.ReadGranularInteger(SourceConnectionIdLength);
}
this.DecodeFrames(array);
}
public override byte[] Encode()
{
byte[] frames = EncodeFrames();
List<byte> result = new List<byte>
{
EncodeTypeField()
};
result.AddRange(ByteHelpers.GetBytes(Version));
result.Add(DestinationConnectionId.Size);
if (DestinationConnectionId.Size > 0)
{
result.AddRange(DestinationConnectionId.ToByteArray());
}
result.Add(SourceConnectionId.Size);
if (SourceConnectionId.Size > 0)
{
result.AddRange(SourceConnectionId.ToByteArray());
}
result.AddRange(frames);
return result.ToArray();
}
private byte EncodeTypeField()
{
byte type = (byte)(Type | ((byte)PacketType << 4) & 0b0011_0000);
return type;
}
private PacketType DecodeTypeFiled(byte type)
{
PacketType result = (PacketType)((type & 0b0011_0000) >> 4);
return result;
}
}
}