/// <summary> /// Visit the message contained within a message/rfc822 or message/news MIME entity. /// </summary> /// <remarks> /// Visits the message contained within a message/rfc822 or message/news MIME entity. /// </remarks> /// <param name="entity">The message/rfc822 or message/news MIME entity.</param> protected virtual void VisitMessage (MessagePart entity) { if (entity.Message != null) entity.Message.Accept (this); }
/// <summary> /// Visit the message/rfc822 or message/news MIME entity. /// </summary> /// <remarks> /// Visits the message/rfc822 or message/news MIME entity. /// </remarks> /// <example> /// <code language="c#" source="Examples\MimeVisitorExamples.cs" region="HtmlPreviewVisitor" /> /// </example> /// <param name="entity">The message/rfc822 or message/news MIME entity.</param> protected internal virtual void VisitMessagePart (MessagePart entity) { VisitMimeEntity (entity); VisitMessage (entity); }
async Task <BoundaryType> ConstructMessagePartAsync(MessagePart part, CancellationToken cancellationToken) { BoundaryType found; if (bounds.Count > 0) { int atleast = Math.Max(ReadAheadSize, GetMaxBoundaryLength()); if (await ReadAheadAsync(atleast, 0, cancellationToken).ConfigureAwait(false) <= 0) { return(BoundaryType.Eos); } unsafe { fixed(byte *inbuf = input) { byte *start = inbuf + inputIndex; byte *inend = inbuf + inputEnd; byte *inptr = start; *inend = (byte)'\n'; while (*inptr != (byte)'\n') { inptr++; } found = CheckBoundary(inputIndex, start, (int)(inptr - start)); switch (found) { case BoundaryType.ImmediateEndBoundary: case BoundaryType.ImmediateBoundary: case BoundaryType.ParentBoundary: return(found); case BoundaryType.ParentEndBoundary: // ignore "From " boundaries, broken mailers tend to include these... if (!IsMboxMarker(start)) { return(found); } break; } } } } // parse the headers... state = MimeParserState.MessageHeaders; if (await StepAsync(cancellationToken).ConfigureAwait(false) == MimeParserState.Error) { // Note: this either means that StepHeaders() found the end of the stream // or an invalid header field name at the start of the message headers, // which likely means that this is not a valid MIME stream? return(BoundaryType.Eos); } var message = new MimeMessage(options, headers, RfcComplianceMode.Loose); var type = GetContentType(null); if (preHeaderBuffer.Length > 0) { message.MboxMarker = new byte[preHeaderLength]; Buffer.BlockCopy(preHeaderBuffer, 0, message.MboxMarker, 0, preHeaderLength); } var entity = options.CreateEntity(type, headers, true); message.Body = entity; if (entity is Multipart) { found = await ConstructMultipartAsync((Multipart)entity, cancellationToken).ConfigureAwait(false); } else if (entity is MessagePart) { found = await ConstructMessagePartAsync((MessagePart)entity, cancellationToken).ConfigureAwait(false); } else { found = await ConstructMimePartAsync((MimePart)entity, cancellationToken).ConfigureAwait(false); } part.Message = message; return(found); }
protected override void VisitMessagePart(MessagePart entity) { // treat message/rfc822 parts as attachments _attachments.Add(entity); }
protected override void VisitMessagePart (MessagePart entity) { // don't descend into message/rfc822 parts }
/// <summary> /// Visit the message/rfc822 or message/news MIME entity. /// </summary> /// <remarks> /// Visits the message/rfc822 or message/news MIME entity. /// </remarks> /// <example> /// <code language="c#" source="Examples\MimeVisitorExamples.cs" region="HtmlPreviewVisitor" /> /// </example> /// <param name="entity">The message/rfc822 or message/news MIME entity.</param> protected internal virtual void VisitMessagePart(MessagePart entity) { VisitMimeEntity(entity); VisitMessage(entity); }
unsafe BoundaryType ConstructMessagePart(MessagePart part, byte* inbuf) { BoundaryType found; if (bounds.Count > 0) { int atleast = Math.Max (ReadAheadSize, GetMaxBoundaryLength ()); if (ReadAhead (inbuf, atleast, 0) <= 0) return BoundaryType.Eos; byte* start = inbuf + inputIndex; byte* inend = inbuf + inputEnd; byte* inptr = start; *inend = (byte) '\n'; while (*inptr != (byte) '\n') inptr++; found = CheckBoundary (inputIndex, start, (int) (inptr - start)); switch (found) { case BoundaryType.ImmediateEndBoundary: case BoundaryType.ImmediateBoundary: case BoundaryType.ParentBoundary: return found; case BoundaryType.ParentEndBoundary: // ignore "From " boundaries, broken mailers tend to include these... if (!IsMboxMarker (start)) return found; break; } } // parse the headers... state = MimeParserState.Headers; if (Step (inbuf) == MimeParserState.Error) { // Note: this either means that StepHeaders() found the end of the stream // or an invalid header field name at the start of the message headers, // which likely means that this is not a valid MIME stream? return BoundaryType.Eos; } var message = new MimeMessage (options, headers); var type = GetContentType (null); var entity = MimeEntity.Create (options, type, headers, true); message.Body = entity; if (entity is Multipart) found = ConstructMultipart ((Multipart) entity, inbuf); else if (entity is MessagePart) found = ConstructMessagePart ((MessagePart) entity, inbuf); else found = ConstructMimePart ((MimePart) entity, inbuf); part.Message = message; return found; }
async Task ConstructMessagePartAsync(MessagePart rfc822, int depth, CancellationToken cancellationToken) { var beginOffset = GetOffset(inputIndex); var beginLineNumber = lineNumber; if (bounds.Count > 0) { int atleast = Math.Max(ReadAheadSize, GetMaxBoundaryLength()); if (await ReadAheadAsync(atleast, 0, cancellationToken).ConfigureAwait(false) <= 0) { OnMimeContentOctets(rfc822, 0); OnMimeContentLines(rfc822, 0); boundary = BoundaryType.Eos; return; } unsafe { fixed(byte *inbuf = input) { byte *start = inbuf + inputIndex; byte *inend = inbuf + inputEnd; byte *inptr = start; *inend = (byte)'\n'; while (*inptr != (byte)'\n') { inptr++; } boundary = CheckBoundary(inputIndex, start, (int)(inptr - start)); switch (boundary) { case BoundaryType.ImmediateEndBoundary: case BoundaryType.ImmediateBoundary: case BoundaryType.ParentBoundary: return; case BoundaryType.ParentEndBoundary: // ignore "From " boundaries, broken mailers tend to include these... if (!IsMboxMarker(start)) { OnMimeContentOctets(rfc822, 0); OnMimeContentLines(rfc822, 0); return; } break; } } } } // parse the headers... state = MimeParserState.MessageHeaders; if (await StepAsync(cancellationToken).ConfigureAwait(false) == MimeParserState.Error) { // Note: this either means that StepHeaders() found the end of the stream // or an invalid header field name at the start of the message headers, // which likely means that this is not a valid MIME stream? boundary = BoundaryType.Eos; return; } var message = new MimeMessage(options, headers, RfcComplianceMode.Loose); var type = GetContentType(null); if (preHeaderBuffer.Length > 0) { message.MboxMarker = new byte[preHeaderLength]; Buffer.BlockCopy(preHeaderBuffer, 0, message.MboxMarker, 0, preHeaderLength); } var entity = options.CreateEntity(type, headers, true, depth); message.Body = entity; OnMimeMessageBegin(message, headerBlockBegin); OnMimeEntityBegin(entity, headerBlockBegin); OnMimeEntityHeadersEnd(entity, headerBlockEnd); OnMimeMessageHeadersEnd(message, headerBlockEnd); if (entity is Multipart) { await ConstructMultipartAsync((Multipart)entity, depth + 1, cancellationToken).ConfigureAwait(false); } else if (entity is MessagePart) { await ConstructMessagePartAsync((MessagePart)entity, depth + 1, cancellationToken).ConfigureAwait(false); } else { await ConstructMimePartAsync((MimePart)entity, cancellationToken).ConfigureAwait(false); } rfc822.Message = message; var endOffset = GetEndOffset(inputIndex); OnMimeEntityEnd(entity, endOffset); OnMimeMessageEnd(message, endOffset); OnMimeContentOctets(rfc822, endOffset - beginOffset); OnMimeContentLines(rfc822, GetLineCount(beginLineNumber)); }
/// <summary> /// Initialize a new instance of the <see cref="MimeMessageEndEventArgs"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MimeMessageEndEventArgs"/>. /// </remarks> /// <param name="message">The message that was parsed.</param> /// <param name="parent">The parent message part.</param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="message"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="parent"/> is <c>null</c>.</para> /// </exception> public MimeMessageEndEventArgs(MimeMessage message, MessagePart parent) : base(message, parent) { }