/// <summary> /// parses input stream and returns list of Frame (not including EndFrame) /// <param name="inputStream">the input stream over the wire</param> /// </summary> public static List <Frame> ParseStream(Stream inputStream) { List <Frame> frames = new List <Frame>(); for (; ;) { FrameHeader frameHeader = FrameHeader.ReadFrameHeader(inputStream); // We do not include EndFrame in the result if (frameHeader.Type == FrameType.EndFrame) { break; } byte[] payloadBuffer = new byte[frameHeader.PayloadSize]; FrameProtocolStreamUtils.ReadChunk(inputStream, payloadBuffer, 0, payloadBuffer.Length); frames.Add(new Frame( type: frameHeader.Type, extendedHeader: frameHeader.ExtendedHeader, payload: payloadBuffer)); } return(frames); }
/// <summary> /// Read header (including extended header) /// Make sure primitive data types are read in BigEndian order. /// </summary> public static FrameHeader ReadFrameHeader(Stream inputStream) { var buffer = new byte[FrameHeaderLength]; FrameProtocolStreamUtils.ReadChunk(inputStream, buffer, 0, FrameHeaderLength); // Read (uint)FrameType int offset = 0; EnsureBigEndianOrder(buffer, offset, length: sizeof(uint)); uint frameTypeValue = BitConverter.ToUInt32(buffer, offset); offset += sizeof(uint); FrameType frameType = (FrameType)frameTypeValue; if (frameType == FrameType.Undefined) { throw new ArgumentException("ReadFrameHeader encountered an undefined frametype."); } // Read (uint)ExtendedHeaderSize // EndFrame should still have the 16 byte header set appropriately. EnsureBigEndianOrder(buffer, offset, length: sizeof(uint)); uint extendedHeaderSize = BitConverter.ToUInt32(buffer, offset); offset += sizeof(uint); // Read (ulong)PayloadSize EnsureBigEndianOrder(buffer, offset, length: sizeof(ulong)); ulong payloadSize = BitConverter.ToUInt64(buffer, offset); if (extendedHeaderSize == 0) { return(new FrameHeader(frameType, 0, payloadSize, null)); } // Read byte[] ExtendedHeader var extendedHeader = new byte[extendedHeaderSize]; FrameProtocolStreamUtils.ReadChunk(inputStream, extendedHeader, 0, extendedHeader.Length); return(new FrameHeader(frameType, extendedHeaderSize, payloadSize, extendedHeader)); }