1
1
use std:: marker:: PhantomData ;
2
2
3
- use compio_buf:: { IoBuf , IoBufMut } ;
4
-
5
3
cfg_if:: cfg_if! {
6
4
if #[ cfg( windows) ] {
7
5
#[ path = "windows.rs" ]
@@ -31,9 +29,9 @@ impl<'a> CMsgIter<'a> {
31
29
/// # Safety
32
30
///
33
31
/// The buffer should contain valid control messages.
34
- pub unsafe fn new < B : IoBuf > ( buffer : & ' a B ) -> Self {
32
+ pub unsafe fn new ( buffer : & ' a [ u8 ] ) -> Self {
35
33
Self {
36
- inner : sys:: CMsgIter :: new ( buffer. as_buf_ptr ( ) , buffer. buf_len ( ) ) ,
34
+ inner : sys:: CMsgIter :: new ( buffer. as_ptr ( ) , buffer. len ( ) ) ,
37
35
_p : PhantomData ,
38
36
}
39
37
}
@@ -52,59 +50,53 @@ impl<'a> Iterator for CMsgIter<'a> {
52
50
}
53
51
54
52
/// Helper to construct control message.
55
- pub struct CMsgBuilder < B > {
53
+ pub struct CMsgBuilder < ' a > {
56
54
inner : sys:: CMsgIter ,
57
- buffer : B ,
58
55
len : usize ,
56
+ _p : PhantomData < & ' a mut ( ) > ,
59
57
}
60
58
61
- impl < B > CMsgBuilder < B > {
62
- /// Finishes building, returns the buffer and the length of the control
63
- /// message.
64
- pub fn build ( self ) -> ( B , usize ) {
65
- ( self . buffer , self . len )
59
+ impl < ' a > CMsgBuilder < ' a > {
60
+ /// Create [`CMsgBuilder`] with the given buffer. The buffer will be zeroed
61
+ /// on creation.
62
+ ///
63
+ /// # Panics
64
+ ///
65
+ /// This function will panic if the buffer is too short or not properly
66
+ /// aligned.
67
+ pub fn new ( buffer : & ' a mut [ u8 ] ) -> Self {
68
+ buffer. fill ( 0 ) ;
69
+ Self {
70
+ inner : sys:: CMsgIter :: new ( buffer. as_ptr ( ) , buffer. len ( ) ) ,
71
+ len : 0 ,
72
+ _p : PhantomData ,
73
+ }
74
+ }
75
+
76
+ /// Finishes building, returns length of the control message.
77
+ pub fn finish ( self ) -> usize {
78
+ self . len
66
79
}
67
80
68
81
/// Try to append a control message entry into the buffer. If the buffer
69
82
/// does not have enough space or is not properly aligned with the value
70
83
/// type, returns `None`.
71
- ///
72
- /// # Safety
73
- ///
74
- /// TODO: This function may be safe? Given that the buffer is zeroed,
75
- /// properly aligned and has enough space, safety conditions of all unsafe
76
- /// functions involved are satisfied, except for `CMSG_*`/`wsa_cmsg_*`, as
77
- /// their safety are not documented.
78
- pub unsafe fn try_push < T > ( & mut self , level : i32 , ty : i32 , value : T ) -> Option < ( ) > {
84
+ pub fn try_push < T > ( & mut self , level : i32 , ty : i32 , value : T ) -> Option < ( ) > {
79
85
if !self . inner . is_aligned :: < T > ( ) || !self . inner . is_space_enough :: < T > ( ) {
80
86
return None ;
81
87
}
82
88
83
- let mut cmsg = self . inner . current_mut ( ) ?;
84
- cmsg. set_level ( level) ;
85
- cmsg. set_ty ( ty) ;
86
- cmsg. set_data ( value) ;
87
-
88
- self . inner . next ( ) ;
89
- self . len += sys:: space_of :: < T > ( ) ;
90
- Some ( ( ) )
91
- }
92
- }
89
+ // SAFETY: the buffer is zeroed and the pointer is valid and aligned
90
+ unsafe {
91
+ let mut cmsg = self . inner . current_mut ( ) ?;
92
+ cmsg. set_level ( level) ;
93
+ cmsg. set_ty ( ty) ;
94
+ cmsg. set_data ( value) ;
93
95
94
- impl < B : IoBufMut > CMsgBuilder < B > {
95
- /// Create [`CMsgBuilder`] with the given buffer. The buffer will be zeroed
96
- /// on creation.
97
- ///
98
- /// # Panics
99
- ///
100
- /// This function will panic if the buffer is too short or not properly
101
- /// aligned.
102
- pub fn new ( mut buffer : B ) -> Self {
103
- buffer. as_mut_slice ( ) . fill ( std:: mem:: MaybeUninit :: zeroed ( ) ) ;
104
- Self {
105
- inner : sys:: CMsgIter :: new ( buffer. as_buf_mut_ptr ( ) , buffer. buf_len ( ) ) ,
106
- buffer,
107
- len : 0 ,
96
+ self . inner . next ( ) ;
97
+ self . len += sys:: space_of :: < T > ( ) ;
108
98
}
99
+
100
+ Some ( ( ) )
109
101
}
110
102
}
0 commit comments