@@ -57,6 +57,8 @@ public class ExperimentalMimeParser : MimeReader, IMimeParser
57
57
byte [ ] preHeaderBuffer ;
58
58
int preHeaderLength ;
59
59
60
+ byte [ ] rawBoundary ;
61
+
60
62
// MimePart content and Multipart preamble/epilogue state
61
63
Stream content ;
62
64
@@ -251,17 +253,26 @@ public void SetStream (Stream stream, bool persistent)
251
253
SetStream ( stream , MimeFormat . Default , persistent ) ;
252
254
}
253
255
254
- void PopEntity ( )
256
+ void PushEntity ( MimeEntity entity )
255
257
{
256
- if ( stack . Count > 1 ) {
257
- var entity = ( MimeEntity ) stack . Pop ( ) ;
258
+ if ( stack . Count > 0 ) {
258
259
var parent = stack . Peek ( ) ;
259
260
260
- if ( parent is MimeMessage message )
261
+ if ( parent is Multipart multipart ) {
262
+ multipart . AddInternal ( entity , rawBoundary ) ;
263
+ rawBoundary = null ;
264
+ } else if ( parent is MimeMessage message ) {
261
265
message . Body = entity ;
262
- else
263
- ( ( Multipart ) parent ) . InternalAdd ( entity ) ;
266
+ }
264
267
}
268
+
269
+ stack . Push ( entity ) ;
270
+ }
271
+
272
+ void PopEntity ( )
273
+ {
274
+ if ( stack . Count > 1 )
275
+ stack . Pop ( ) ;
265
276
}
266
277
267
278
#region Mbox Events
@@ -390,6 +401,12 @@ protected override void OnMimeMessageBegin (long beginOffset, int beginLineNumbe
390
401
Buffer . BlockCopy ( preHeaderBuffer , 0 , message . MboxMarker , 0 , preHeaderLength ) ;
391
402
}
392
403
404
+ if ( stack . Count > 0 ) {
405
+ var rfc822 = ( MessagePart ) stack . Peek ( ) ;
406
+
407
+ rfc822 . Message = message ;
408
+ }
409
+
393
410
stack . Push ( message ) ;
394
411
}
395
412
@@ -408,12 +425,8 @@ protected override void OnMimeMessageBegin (long beginOffset, int beginLineNumbe
408
425
/// <param name="cancellationToken">The cancellation token.</param>
409
426
protected override void OnMimeMessageEnd ( long beginOffset , int beginLineNumber , long headersEndOffset , long endOffset , int lines , CancellationToken cancellationToken )
410
427
{
411
- if ( stack . Count > 1 ) {
412
- var message = ( MimeMessage ) stack . Pop ( ) ;
413
- var rfc822 = ( MessagePart ) stack . Peek ( ) ;
414
-
415
- rfc822 . Message = message ;
416
- }
428
+ if ( stack . Count > 1 )
429
+ stack . Pop ( ) ;
417
430
}
418
431
419
432
#endregion MimeMessage Events
@@ -436,7 +449,7 @@ protected override void OnMimePartBegin (ContentType contentType, long beginOffs
436
449
var toplevel = stack . Count > 0 && stack . Peek ( ) is MimeMessage ;
437
450
var part = Options . CreateEntity ( contentType , headers , toplevel , depth ) ;
438
451
439
- stack . Push ( part ) ;
452
+ PushEntity ( part ) ;
440
453
}
441
454
442
455
/// <summary>
@@ -545,7 +558,7 @@ protected override void OnMessagePartBegin (ContentType contentType, long beginO
545
558
var rfc822 = Options . CreateEntity ( contentType , headers , toplevel , depth ) ;
546
559
547
560
parsingMessageHeaders = true ;
548
- stack . Push ( rfc822 ) ;
561
+ PushEntity ( rfc822 ) ;
549
562
depth ++ ;
550
563
}
551
564
@@ -589,27 +602,10 @@ protected override void OnMultipartBegin (ContentType contentType, long beginOff
589
602
var toplevel = stack . Count > 0 && stack . Peek ( ) is MimeMessage ;
590
603
var multipart = Options . CreateEntity ( contentType , headers , toplevel , depth ) ;
591
604
592
- stack . Push ( multipart ) ;
605
+ PushEntity ( multipart ) ;
593
606
depth ++ ;
594
607
}
595
608
596
- /// <summary>
597
- /// Called when a multipart end boundary is encountered in the stream.
598
- /// </summary>
599
- /// <remarks>
600
- /// Called when a multipart end boundary is encountered in the stream.
601
- /// </remarks>
602
- /// <param name="beginOffset">The offset into the stream where the boundary marker began.</param>
603
- /// <param name="lineNumber">The line number where the boundary marker was found in the stream.</param>
604
- /// <param name="endOffset">The offset into the stream where the boundary marker ended.</param>
605
- /// <param name="cancellationToken">The cancellation token.</param>
606
- protected override void OnMultipartEndBoundaryEnd ( long beginOffset , int lineNumber , long endOffset , CancellationToken cancellationToken )
607
- {
608
- var multipart = ( Multipart ) stack . Peek ( ) ;
609
-
610
- multipart . WriteEndBoundary = true ;
611
- }
612
-
613
609
/// <summary>
614
610
/// Called when the beginning of the preamble of a multipart is encountered in the stream.
615
611
/// </summary>
@@ -663,6 +659,47 @@ protected override void OnMultipartPreambleEnd (long beginOffset, int beginLineN
663
659
content = null ;
664
660
}
665
661
662
+ /// <summary>
663
+ /// Called when a multipart boundary is encountered in the stream.
664
+ /// </summary>
665
+ /// <remarks>
666
+ /// Called when a multipart boundary is encountered in the stream.
667
+ /// </remarks>
668
+ /// <param name="buffer">The buffer containing the boundary marker.</param>
669
+ /// <param name="startIndex">The index denoting the starting position of the boundary marker within the buffer.</param>
670
+ /// <param name="count">The length of the boundary marker within the buffer, in bytes.</param>
671
+ /// <param name="beginOffset">The offset into the stream where the boundary marker began.</param>
672
+ /// <param name="lineNumber">The line number where the boundary marker exists within the stream.</param>
673
+ /// <param name="cancellationToken">The cancellation token.</param>
674
+ protected override void OnMultipartBoundaryRead ( byte [ ] buffer , int startIndex , int count , long beginOffset , int lineNumber , CancellationToken cancellationToken )
675
+ {
676
+ rawBoundary = new byte [ count ] ;
677
+
678
+ Buffer . BlockCopy ( buffer , startIndex , rawBoundary , 0 , count ) ;
679
+ }
680
+
681
+ /// <summary>
682
+ /// Called when a multipart end boundary is encountered in the stream.
683
+ /// </summary>
684
+ /// <remarks>
685
+ /// Called when a multipart end boundary is encountered in the stream.
686
+ /// </remarks>
687
+ /// <param name="buffer">The buffer containing the boundary marker.</param>
688
+ /// <param name="startIndex">The index denoting the starting position of the boundary marker within the buffer.</param>
689
+ /// <param name="count">The length of the boundary marker within the buffer, in bytes.</param>
690
+ /// <param name="beginOffset">The offset into the stream where the boundary marker began.</param>
691
+ /// <param name="lineNumber">The line number where the boundary marker exists within the stream.</param>
692
+ /// <param name="cancellationToken">The cancellation token.</param>
693
+ protected override void OnMultipartEndBoundaryRead ( byte [ ] buffer , int startIndex , int count , long beginOffset , int lineNumber , CancellationToken cancellationToken )
694
+ {
695
+ var multipart = ( Multipart ) stack . Peek ( ) ;
696
+ var rawEndBoundary = new byte [ count ] ;
697
+
698
+ Buffer . BlockCopy ( buffer , startIndex , rawEndBoundary , 0 , count ) ;
699
+
700
+ multipart . RawEndBoundary = rawEndBoundary ;
701
+ }
702
+
666
703
/// <summary>
667
704
/// Called when the beginning of the epilogue of a multipart is encountered in the stream.
668
705
/// </summary>
0 commit comments