/// <summary> Parse raw data.</summary> public void ParseRawData() { using (var rawData = new MemoryStream(this.Rawdata)) { using (var dataStream = new LineReader(rawData, 1024, Encoding.ASCII)) { bool isFinalPart; this.DocumentRoot = this.ParseMIMEpart(this, dataStream, null, out isFinalPart); } } //DocumentRoot.PrintStats(); }
/// <summary> Parse mim epart.</summary> /// <param name="mimEemail"> The mim eemail. </param> /// <param name="dataStream"> The data stream. </param> /// <param name="parentPart"> The parent part. </param> /// <param name="finalPart"> [out] The final part. </param> /// <returns> A MIMEpart.</returns> private MIMEpart ParseMIMEpart(MIMEemail mimEemail, LineReader dataStream, MIMEpart parentPart, out bool finalPart) { var currentPart = new MIMEpart(mimEemail); if (parentPart != null) { currentPart.Encoding = parentPart.Encoding; } finalPart = false; var boundaryFound = false; // parse IMF headers this.ParseHeaders(dataStream, currentPart, parentPart, Encoding.ASCII, out boundaryFound); if (boundaryFound) // boundary was found => empty content { currentPart.HasEmptyContent = true; return(currentPart); } // if current part is also multipart parse all sub parts if (currentPart.IsMultiPart) { var isFinalPart = false; currentPart.RawContent = this.ReadData(dataStream, currentPart.PartBoundary, currentPart.ContentBoundary, currentPart.Encoding, out isFinalPart); while (!isFinalPart) { currentPart.AddPart(this.ParseMIMEpart(mimEemail, dataStream, currentPart, out isFinalPart)); } } else { // this is not multipart part => read part content : if (parentPart == null || parentPart.ContentBoundary == null) { // boundary was not set or specified - read till end of IMF data : finalPart = true; //currentPart.RawContent = dataStream.ReadToEnd(); //currentPart.RawContent = currentPart.encoding.GetString(dataStream.ReadBytes(int.MaxValue)); // currentPart.RawContent = dataStream.ReadToEnd(); currentPart.RawContent = currentPart.Encoding.GetString(dataStream.ReadBytes((int)(dataStream.BaseStream.Length - dataStream.BaseStream.Position))); } else { bool isDataFinalPart; currentPart.RawContent = currentPart.RawContent = this.ReadData(dataStream, parentPart.PartBoundary, parentPart.ContentBoundary, currentPart.Encoding, out isDataFinalPart); if (isDataFinalPart) { finalPart = true; } } } if (currentPart.RawContent == null) { currentPart.HasEmptyContent = true; } return(currentPart); }
/// <summary> Parse headers.</summary> /// <param name="dataStream"> The data stream. </param> /// <param name="currentPart"> The current part. </param> /// <param name="parentPart"> The parent part. </param> /// <param name="encoding"> The encoding. </param> /// <param name="boundaryFound"> [out] The boundary found. </param> public void ParseHeaders(LineReader dataStream, MIMEpart currentPart, MIMEpart parentPart, Encoding encoding, out bool boundaryFound) { var separator = new char[] { ':' }; var line = String.Empty; MIMEheader currentHeader = null; boundaryFound = false; while (line != null) { // read line by line //line = dataStream.ReadLine();) line = dataStream.ReadLine(encoding); if (line != null) { // break whene empty line (headers delimiter was found) // or end of document was reached if (line.Equals(String.Empty) || line.Length == 0) { break; } // check for parrent boundary line - in case of empty part conent if (parentPart != null && parentPart.ContentBoundary != null) { if (line.Equals(parentPart.ContentBoundary) || line.Equals(parentPart.PartBoundary)) { // content is empty - break boundaryFound = true; break; } } // store line to raw headers string currentPart.RawHeaders += line + Environment.NewLine; // handle multiline headers : if (char.IsWhiteSpace(line[0])) { // if header line begins with white character // add its conent to previous header value if (currentHeader != null) { currentHeader.Value += line.Trim(); } } else { // next header was detected : if (currentHeader != null) { // if this is not the first one - store previous header currentPart.AddHeader(currentHeader); currentHeader = null; } // split first part of header to type and value parts : var parts = line.Split(separator, 2); if (parts.Count() == 2) { currentHeader = new MIMEheader(); currentHeader.Type = parts[0].Trim(); currentHeader.Value = parts[1].Trim(); } } } } // store last found header before exit if (currentHeader != null) { currentPart.AddHeader(currentHeader); } }
/// <summary> Add children part to list of childrens parts.</summary> /// <param name="part"> The part. </param> public void AddPart(MIMEpart part) { this.ContainedParts.Add(part); }