// TODO: this should probably better return class instance for the purpose of using its methods, e.g. ToString, but then we lose the FieldMeta descriptions public List <ParsedEvent> ParseStream(TcpStream tcpStream, ParseMode parseMode = ParseMode.Root, long startingStreamPosition = 0) { var events = new List <ParsedEvent>(); var stream = new MemoryStream(); lock (tcpStream) { var position = tcpStream.Position; tcpStream.Position = startingStreamPosition; tcpStream.CopyTo(stream); tcpStream.Position = position; } _br = new BinaryReader(stream); _br.BaseStream.Position = 0; while (_br.BaseStream.Position < _br.BaseStream.Length) { try { var positionBeforeRead = _br.BaseStream.Position; var newParsedEvent = new ParsedEvent { Offset = positionBeforeRead + startingStreamPosition, Sender = tcpStream.Sender, ParseMode = parseMode }; var packetData = ReadEvent(out var opCode, parseMode); if (packetData.Count == 0) { break; } newParsedEvent.OpCode = opCode; newParsedEvent.Length = _br.BaseStream.Position - positionBeforeRead; newParsedEvent.Data = packetData; newParsedEvent.Time = tcpStream.PacketAtOffset(startingStreamPosition + _br.BaseStream.Position).Time; events.Add(newParsedEvent); } catch (Exception e) { // Safe exit break; } } _br.Dispose(); _br = null; return(events); }