private BaseFrame DeserializeControlFrame(byte[] data)
{
FrameType type = GetFrameType(data);
ControlFrame frame = new ControlFrame();
switch (type)
{
case FrameType.RTS:
frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
frame.StatusCode = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));
break;
case FrameType.Headers:
case FrameType.SynReply:
ParseControlFrameHeader(ref frame, data);
frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
ParseControlFrameHeaders(ref frame, data, 12);
break;
case FrameType.SynStream:
ParseControlFrameHeader(ref frame, data);
frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
frame.AssociatedToStreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));
frame.Priority = (byte)(data[16] >> 5);
frame.Slot = data[17];
ParseControlFrameHeaders(ref frame, data, 18);
break;
case FrameType.Settings:
int numberOfEntries = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
frame = new SettingsFrame(numberOfEntries);
int headersOffset = 12;
for (int i = 0; i < numberOfEntries; i++)
{
int key = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, headersOffset, 4));
headersOffset += 4;
int value = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, headersOffset, 4));
headersOffset += 4;
frame.SettingsHeaders.Add(key, value);
}
ParseControlFrameHeader(ref frame, data);
break;
case FrameType.GoAway:
int lastSeenGoodStreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
StatusCode status = StatusCode.Success;
if (data.Length > 12)
status = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));
frame = new GoAwayFrame(lastSeenGoodStreamId, status);
ParseControlFrameHeader(ref frame, data);
break;
case FrameType.Ping:
int streamID = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 4, 4));
frame = new ControlFrame { StreamId = streamID };
ParseControlFrameHeader(ref frame, data);
break;
case FrameType.WindowUpdate:
int streamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 4, 4));
int deltaWindowSize = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
frame = new WindowUpdateFrame(streamId, deltaWindowSize);
ParseControlFrameHeader(ref frame, data);
break;
}
frame.Type = type;
return frame;
}