@@ -440,8 +440,7 @@ impl<'buf> RecvAncillaryBuffer<'buf> {
440
440
pub fn drain ( & mut self ) -> AncillaryDrain < ' _ > {
441
441
AncillaryDrain {
442
442
messages : messages:: Messages :: new ( & mut self . buffer [ self . read ..] [ ..self . length ] ) ,
443
- read : & mut self . read ,
444
- length : & mut self . length ,
443
+ read_and_length : Some ( ( & mut self . read , & mut self . length ) ) ,
445
444
}
446
445
}
447
446
}
@@ -474,25 +473,40 @@ pub struct AncillaryDrain<'buf> {
474
473
messages : messages:: Messages < ' buf > ,
475
474
476
475
/// Increment the number of messages we've read.
477
- read : & ' buf mut usize ,
478
-
479
476
/// Decrement the total length.
480
- length : & ' buf mut usize ,
477
+ read_and_length : Option < ( & ' buf mut usize , & ' buf mut usize ) > ,
481
478
}
482
479
483
480
impl < ' buf > AncillaryDrain < ' buf > {
484
- /// A closure that converts a message into a [`RecvAncillaryMessage`].
485
- fn cvt_msg (
486
- read : & mut usize ,
487
- length : & mut usize ,
481
+ /// Create an iterator for control messages that were received without [`RecvAncillaryBuffer`].
482
+ ///
483
+ /// # Safety
484
+ ///
485
+ /// The buffer must contain valid message data (or be empty).
486
+ pub unsafe fn parse ( buffer : & ' buf mut [ u8 ] ) -> Self {
487
+ Self {
488
+ messages : messages:: Messages :: new ( buffer) ,
489
+ read_and_length : None ,
490
+ }
491
+ }
492
+
493
+ fn advance (
494
+ read_and_length : & mut Option < ( & ' buf mut usize , & ' buf mut usize ) > ,
488
495
msg : & c:: cmsghdr ,
489
496
) -> Option < RecvAncillaryMessage < ' buf > > {
490
- unsafe {
491
- // Advance the `read` pointer.
497
+ // Advance the `read` pointer.
498
+ if let Some ( ( read , length ) ) = read_and_length {
492
499
let msg_len = msg. cmsg_len as usize ;
493
- * read += msg_len;
494
- * length -= msg_len;
500
+ * * read += msg_len;
501
+ * * length -= msg_len;
502
+ }
503
+
504
+ Self :: cvt_msg ( msg)
505
+ }
495
506
507
+ /// A closure that converts a message into a [`RecvAncillaryMessage`].
508
+ fn cvt_msg ( msg : & c:: cmsghdr ) -> Option < RecvAncillaryMessage < ' buf > > {
509
+ unsafe {
496
510
// Get a pointer to the payload.
497
511
let payload = c:: CMSG_DATA ( msg) ;
498
512
let payload_len = msg. cmsg_len as usize - c:: CMSG_LEN ( 0 ) as usize ;
@@ -528,55 +542,46 @@ impl<'buf> Iterator for AncillaryDrain<'buf> {
528
542
type Item = RecvAncillaryMessage < ' buf > ;
529
543
530
544
fn next ( & mut self ) -> Option < Self :: Item > {
531
- let read = & mut self . read ;
532
- let length = & mut self . length ;
533
- self . messages . find_map ( |ev| Self :: cvt_msg ( read, length, ev) )
545
+ self . messages
546
+ . find_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
534
547
}
535
548
536
549
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
537
550
let ( _, max) = self . messages . size_hint ( ) ;
538
551
( 0 , max)
539
552
}
540
553
541
- fn fold < B , F > ( self , init : B , f : F ) -> B
554
+ fn fold < B , F > ( mut self , init : B , f : F ) -> B
542
555
where
543
556
Self : Sized ,
544
557
F : FnMut ( B , Self :: Item ) -> B ,
545
558
{
546
- let read = self . read ;
547
- let length = self . length ;
548
559
self . messages
549
- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
560
+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
550
561
. fold ( init, f)
551
562
}
552
563
553
- fn count ( self ) -> usize {
554
- let read = self . read ;
555
- let length = self . length ;
564
+ fn count ( mut self ) -> usize {
556
565
self . messages
557
- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
566
+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
558
567
. count ( )
559
568
}
560
569
561
- fn last ( self ) -> Option < Self :: Item >
570
+ fn last ( mut self ) -> Option < Self :: Item >
562
571
where
563
572
Self : Sized ,
564
573
{
565
- let read = self . read ;
566
- let length = self . length ;
567
574
self . messages
568
- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
575
+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
569
576
. last ( )
570
577
}
571
578
572
- fn collect < B : FromIterator < Self :: Item > > ( self ) -> B
579
+ fn collect < B : FromIterator < Self :: Item > > ( mut self ) -> B
573
580
where
574
581
Self : Sized ,
575
582
{
576
- let read = self . read ;
577
- let length = self . length ;
578
583
self . messages
579
- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
584
+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
580
585
. collect ( )
581
586
}
582
587
}
0 commit comments