private ImapResponse ParseResponce(ByteString line, ref IParsingContext parsingContext) { // response = *(continue-req / response-data) response-done // continue-req = "+" SP (resp-text / base64) CRLF if (line.StartsWith(continueReqMark)) return new ImapCommandContinuationRequest(line.ToString(2, line.Length - 4)); // remove leading "+" SP and trailing CRLF // greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF // response-done = response-tagged / response-fatal // response-data = "*" SP (resp-cond-state / resp-cond-bye / // mailbox-data / message-data / capability-data) CRLF // response-fatal = "*" SP resp-cond-bye CRLF // ; Server closes connection immediately // response-tagged = tag SP resp-cond-state CRLF // ("*" / tag) SP var tagSep = line.IndexOf(Octets.SP); if (tagSep == -1) // response-done and response-data must contain SP throw new ImapMalformedResponseException("malformed response-done/response-data", line.ToString()); var untagged = (tagSep == 1 && line[0] == ImapOctets.Asterisk); // ("OK" / "BAD" / "NO" / "BYE" / "PREAUTH" / text) SP var respCondSep = line.IndexOf(Octets.SP, tagSep + 1); var cond = ImapResponseCondition.Undefined; if (respCondSep == -1) { if (!untagged) throw new ImapMalformedResponseException("malformed response-data", line.ToString()); //else // '* SEARCH\r\n' (mailbox-data which contains no SP) } else { cond = ParseCondition(line.Substring(tagSep + 1, respCondSep - tagSep - 1)); } if (cond != ImapResponseCondition.Undefined || line.StartsWith(respCondMark)) { // resp-cond-auth / resp-cond-state / resp-cond-bye var responseText = ParseRespText((cond == ImapResponseCondition.Undefined) ? line.Substring(tagSep + 1) : line.Substring(respCondSep + 1)); if (untagged) return new ImapUntaggedStatusResponse((ImapResponseCondition)cond, responseText); else return new ImapTaggedStatusResponse(line.ToString(0, tagSep), (ImapResponseCondition)cond, responseText); } // mailbox-data / message-data / capability-data etc. return ParseDataResponse(line, ref parsingContext); }
private static MimeMessage ParseBody(LineOrientedStream stream, MimeHeaderCollection headers) { var message = new MimeMessage(headers); ParseContentType(message); ParseContentTransferEncoding(message); ParseContentDisposition(message); // read and parse content MemoryStream contentStream; if (message.MimeType == null || !message.MimeType.TypeEquals("multipart")) { contentStream = new MemoryStream(1024); stream.CopyTo(contentStream, MimeFormat.Standard.Folding); message.Content = contentStream; return message; } // multipart/* var parts = new List<MimeMessage>(); var delimiter = new ByteString("--" + message.Boundary); var closeDelimiter = new ByteString("--" + message.Boundary + "--"); MemoryStream body = null; ByteString line = null; ByteString lastLine = null; contentStream = new MemoryStream(1024); for (;;) { if (lastLine != null) contentStream.Write(lastLine.ByteArray, 0, lastLine.Length); var l = stream.ReadLine(); if (l == null) break; lastLine = line; line = new ByteString(l); if (line.StartsWith(delimiter)) { if (lastLine != null) { if (lastLine.EndsWith(Octets.CRLF)) // CRLF "--" boundary contentStream.Write(lastLine.ByteArray, 0, lastLine.Length - 2); else // LF "--" boundary or CR "--" boundary contentStream.Write(lastLine.ByteArray, 0, lastLine.Length - 1); } contentStream.Position = 0; if (body == null) body = contentStream; else parts.Add(Parse(contentStream)); if (line.StartsWith(closeDelimiter)) break; else contentStream = new MemoryStream(1024); lastLine = null; } } message.Content = body; message.SubParts.AddRange(parts); return message; }
public void TestStartsWithString() { var str = new ByteString("abcde"); Assert.IsTrue(str.StartsWith("abc")); Assert.IsTrue(str.StartsWith("abcde")); Assert.IsFalse(str.StartsWith("abd")); Assert.IsFalse(str.StartsWith("abcdef")); }