@@ -440,8 +440,7 @@ impl<'buf> RecvAncillaryBuffer<'buf> {
440440 pub fn drain ( & mut self ) -> AncillaryDrain < ' _ > {
441441 AncillaryDrain {
442442 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 ) ) ,
445444 }
446445 }
447446}
@@ -474,25 +473,40 @@ pub struct AncillaryDrain<'buf> {
474473 messages : messages:: Messages < ' buf > ,
475474
476475 /// Increment the number of messages we've read.
477- read : & ' buf mut usize ,
478-
479476 /// Decrement the total length.
480- length : & ' buf mut usize ,
477+ read_and_length : Option < ( & ' buf mut usize , & ' buf mut usize ) > ,
481478}
482479
483480impl < ' 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 ) > ,
488495 msg : & c:: cmsghdr ,
489496 ) -> Option < RecvAncillaryMessage < ' buf > > {
490- unsafe {
491- // Advance the `read` pointer.
497+ // Advance the `read` pointer.
498+ if let Some ( ( read , length ) ) = read_and_length {
492499 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+ }
495506
507+ /// A closure that converts a message into a [`RecvAncillaryMessage`].
508+ fn cvt_msg ( msg : & c:: cmsghdr ) -> Option < RecvAncillaryMessage < ' buf > > {
509+ unsafe {
496510 // Get a pointer to the payload.
497511 let payload = c:: CMSG_DATA ( msg) ;
498512 let payload_len = msg. cmsg_len as usize - c:: CMSG_LEN ( 0 ) as usize ;
@@ -528,55 +542,46 @@ impl<'buf> Iterator for AncillaryDrain<'buf> {
528542 type Item = RecvAncillaryMessage < ' buf > ;
529543
530544 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) )
534547 }
535548
536549 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
537550 let ( _, max) = self . messages . size_hint ( ) ;
538551 ( 0 , max)
539552 }
540553
541- fn fold < B , F > ( self , init : B , f : F ) -> B
554+ fn fold < B , F > ( mut self , init : B , f : F ) -> B
542555 where
543556 Self : Sized ,
544557 F : FnMut ( B , Self :: Item ) -> B ,
545558 {
546- let read = self . read ;
547- let length = self . length ;
548559 self . messages
549- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
560+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
550561 . fold ( init, f)
551562 }
552563
553- fn count ( self ) -> usize {
554- let read = self . read ;
555- let length = self . length ;
564+ fn count ( mut self ) -> usize {
556565 self . messages
557- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
566+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
558567 . count ( )
559568 }
560569
561- fn last ( self ) -> Option < Self :: Item >
570+ fn last ( mut self ) -> Option < Self :: Item >
562571 where
563572 Self : Sized ,
564573 {
565- let read = self . read ;
566- let length = self . length ;
567574 self . messages
568- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
575+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
569576 . last ( )
570577 }
571578
572- fn collect < B : FromIterator < Self :: Item > > ( self ) -> B
579+ fn collect < B : FromIterator < Self :: Item > > ( mut self ) -> B
573580 where
574581 Self : Sized ,
575582 {
576- let read = self . read ;
577- let length = self . length ;
578583 self . messages
579- . filter_map ( |ev| Self :: cvt_msg ( read , length , ev) )
584+ . filter_map ( |ev| Self :: advance ( & mut self . read_and_length , ev) )
580585 . collect ( )
581586 }
582587}
0 commit comments