/* Assume (for now) the message starts with the postmark, * Further assume the message structure * postmark\r\n * headers\r\n * \r\n * body */ public async Task <ParseResult> Parse(MessageReader reader) { postmark = new Postmark(entity); if ((await postmark.Parse(reader)) == ParseResult.Failed) { throw new ParsingFailedException("postmark is not found"); } email = new Email(entity); ParseResult res = await email.Parse(reader); if (res != ParseResult.Eof && res != ParseResult.Postmark) { await ConsumeToEnd(reader); } SetSize(); return(res); }
/* Assume (for now) the message starts with the postmark, Further assume the message structure postmark\r\n headers\r\n \r\n body */ public async Task<ParseResult> Parse(MessageReader reader) { postmark = new Postmark(entity); if ((await postmark.Parse(reader)) == ParseResult.Failed) throw new ParsingFailedException("postmark is not found"); email = new Email(entity); ParseResult res = await email.Parse(reader); if (res != ParseResult.Eof && res != ParseResult.Postmark) await ConsumeToEnd(reader); SetSize(); return res; }
public async Task<ParseResult> Parse(MessageReader reader, ContentType type = ContentType.Text, ContentSubtype subtype = ContentSubtype.Plain, Boundary boundary = null) { if (type == ContentType.Multipart) { dataType = DataType.Multipart; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return ParseResult.Eof; } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably missing boundary? reader.PushCacheLine(line); SetSize(); return ParseResult.Postmark; } WriteWithCrlf(line); // find open boundary if (boundary.IsOpen(line)) { Email email = null; ParseResult res; do { // consume all parts, consisting of header (optional) and content // the boundary token delimets the part // the close boundary completes multipart parsing // content in the multipart is responsible for consuming it's delimeter (end) // exception is the last part which is also multipart email = new Email(entity); Add(email); } while ((res = await email.Parse(reader, type, subtype, boundary)) == ParseResult.OkMultipart); // Ok // if the last part is a multipart or message? itself then it doesn't consume the close boundary // or more parts, continue parsing until all parts and close boundary are consumed /*if (Ok(res) && (data.Last<Email>().content.dataType == DataType.Multipart || data.Last<Email>().content.dataType == DataType.Message))*/ if (res == ParseResult.Ok && boundary.NotClosed()) continue; if (res != ParseResult.Failed) SetSize(); return res; } else if (boundary.IsClose(line, reader)) { SetSize(); return ParseResult.Ok; // OkMultipart } } } else if (type == ContentType.Message) { dataType = DataType.Message; Email email = new Email(entity); Add(email); ParseResult res = await email.Parse(reader, type, subtype, boundary); if (res != ParseResult.Failed) SetSize(); return res; } else { dataType = DataType.Data; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return ParseResult.Eof; } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably closing boundary is missing ? reader.PushCacheLine(line); SetSize(); return ParseResult.Postmark; } else if (boundary != null && boundary.IsOpen(line)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return ParseResult.OkMultipart; //Ok } else if (boundary != null && boundary.IsClose(line, reader)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return ParseResult.Ok; //OkMultipart } else WriteWithCrlf(line); } } }
public async Task <ParseResult> Parse(MessageReader reader, ContentType type = ContentType.Text, ContentSubtype subtype = ContentSubtype.Plain, Boundary boundary = null) { if (type == ContentType.Multipart) { dataType = DataType.Multipart; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return(ParseResult.Eof); } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably missing boundary? reader.PushCacheLine(line); SetSize(); return(ParseResult.Postmark); } WriteWithCrlf(line); // find open boundary if (boundary.IsOpen(line)) { Email email = null; ParseResult res; do { // consume all parts, consisting of header (optional) and content // the boundary token delimets the part // the close boundary completes multipart parsing // content in the multipart is responsible for consuming it's delimeter (end) // exception is the last part which is also multipart email = new Email(entity); Add(email); } while ((res = await email.Parse(reader, type, subtype, boundary)) == ParseResult.OkMultipart); // Ok // if the last part is a multipart or message? itself then it doesn't consume the close boundary // or more parts, continue parsing until all parts and close boundary are consumed /*if (Ok(res) && (data.Last<Email>().content.dataType == DataType.Multipart || * data.Last<Email>().content.dataType == DataType.Message))*/ if (res == ParseResult.Ok && boundary.NotClosed()) { continue; } if (res != ParseResult.Failed) { SetSize(); } return(res); } else if (boundary.IsClose(line, reader)) { SetSize(); return(ParseResult.Ok); // OkMultipart } } } else if (type == ContentType.Message) { dataType = DataType.Message; Email email = new Email(entity); Add(email); ParseResult res = await email.Parse(reader, type, subtype, boundary); if (res != ParseResult.Failed) { SetSize(); } return(res); } else { dataType = DataType.Data; while (true) { String line = await reader.ReadLineAsync(); if (line == null) { SetSize(); return(ParseResult.Eof); } else if (EmailParser.IsPostmark(line)) { // consumed too much, probably closing boundary is missing ? reader.PushCacheLine(line); SetSize(); return(ParseResult.Postmark); } else if (boundary != null && boundary.IsOpen(line)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return(ParseResult.OkMultipart); //Ok } else if (boundary != null && boundary.IsClose(line, reader)) { SetSize(); RewindLastCrlfSize(); WriteWithCrlf(line); return(ParseResult.Ok); //OkMultipart } else { WriteWithCrlf(line); } } } }