public static Tuple<StreamFrame, int> FromByteArray(byte[] bytes, int index)
{
var finFlag = (bytes[index] & (1 << 6)) != 0;
var dataLengthFlag = (bytes[index] & (1 << 5)) != 0;
var olenIndex = (bytes[index] >> 2) & 7;
var frame = new StreamFrame
{
Fin = finFlag,
_olen = (byte)(olenIndex == 0 ? 0 : olenIndex + 1),
_slen = (byte)(bytes[index] & 3)
};
switch (frame._slen)
{
case 0:
frame._streamId = bytes[index + 1];
break;
case 1:
frame._streamId = BitConverter.ToUInt16(bytes, index + 1);
break;
case 2:
var buf = new byte[4];
Array.Copy(bytes, index + 1, buf, 1, 3);
frame._streamId = BitConverter.ToUInt32(buf,0);
break;
case 3:
frame._streamId = BitConverter.ToUInt32(bytes, index + 1);
break;
}
// ReSharper disable PossibleInvalidOperationException
frame._metadataLength = 1 + (frame._slen.Value + 1) + (frame._olen.Value == 0 ? 0 : frame._olen.Value + 1) + (dataLengthFlag ? 2 : 0);
// ReSharper restore PossibleInvalidOperationException
index += frame._metadataLength.Value;
var dataLength = dataLengthFlag ? BitConverter.ToUInt16(bytes, index - 2) : bytes.Length - index - 1;
frame._data = new byte[dataLength];
Array.Copy(bytes, index, frame._data, 0, dataLength);
index += dataLength;
return new Tuple<StreamFrame, int>(frame, index);
}