• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::fmt::{self, Debug};
2 use std::marker::PhantomData;
3 use std::slice;
4 
5 use winapi::shared::ws2def::WSABUF;
6 
7 /// Cross platform binary compatible iovec.
8 pub type IoBuf = WSABUF;
9 
10 /// Cross platform stub to create a platform specific IoBuf.
create_iobuf(addr: *mut u8, len: usize) -> IoBuf11 pub fn create_iobuf(addr: *mut u8, len: usize) -> IoBuf {
12     WSABUF {
13         buf: addr as *mut i8,
14         len: len as u32,
15     }
16 }
17 
18 /// This type is essentialy `std::io::IoBufMut`, and guaranteed to be ABI-compatible with
19 /// `WSABUF`; however, it does NOT automatically deref to `&mut [u8]`, which is critical
20 /// because it can point to guest memory. (Guest memory is implicitly mutably borrowed by the
21 /// guest, so another mutable borrow would violate Rust assumptions about references.)
22 #[derive(Copy, Clone)]
23 #[repr(transparent)]
24 pub struct IoBufMut<'a> {
25     buf: WSABUF,
26     phantom: PhantomData<&'a mut [u8]>,
27 }
28 
29 impl<'a> IoBufMut<'a> {
new(buf: &mut [u8]) -> IoBufMut<'a>30     pub fn new(buf: &mut [u8]) -> IoBufMut<'a> {
31         // Safe because buf's memory is of the supplied length, and
32         // guaranteed to exist for the lifetime of the returned value.
33         unsafe { Self::from_raw_parts(buf.as_mut_ptr(), buf.len()) }
34     }
35 
36     /// Creates a `IoBufMut` from a pointer and a length.
37     ///
38     /// # Safety
39     ///
40     /// In order to use this method safely, `addr` must be valid for reads and writes of `len` bytes
41     /// and should live for the entire duration of lifetime `'a`.
from_raw_parts(addr: *mut u8, len: usize) -> IoBufMut<'a>42     pub unsafe fn from_raw_parts(addr: *mut u8, len: usize) -> IoBufMut<'a> {
43         IoBufMut {
44             buf: WSABUF {
45                 buf: addr as *mut i8,
46                 len: len as u32,
47             },
48             phantom: PhantomData,
49         }
50     }
51 
52     /// Creates a `IoBufMut` from an IoBuf.
53     ///
54     /// # Safety
55     ///
56     /// In order to use this method safely, `iobuf` must be valid for reads and writes through its
57     /// length and should live for the entire duration of lifetime `'a`.
from_iobuf(iobuf: IoBuf) -> IoBufMut<'a>58     pub unsafe fn from_iobuf(iobuf: IoBuf) -> IoBufMut<'a> {
59         IoBufMut {
60             buf: iobuf,
61             phantom: PhantomData,
62         }
63     }
64 
65     /// Advance the internal position of the buffer.
66     ///
67     /// Panics if `count > self.len()`.
advance(&mut self, _count: usize)68     pub fn advance(&mut self, _count: usize) {
69         unimplemented!()
70     }
71 
72     /// Shorten the length of the buffer.
73     ///
74     /// Has no effect if `len > self.len()`.
truncate(&mut self, _len: usize)75     pub fn truncate(&mut self, _len: usize) {
76         unimplemented!()
77     }
78 
79     #[inline]
len(&self) -> usize80     pub fn len(&self) -> usize {
81         self.buf.len as usize
82     }
83 
84     /// Gets a const pointer to this slice's memory.
85     #[inline]
as_ptr(&self) -> *const u886     pub fn as_ptr(&self) -> *const u8 {
87         self.buf.buf as *const u8
88     }
89 
90     /// Gets a mutable pointer to this slice's memory.
91     #[inline]
as_mut_ptr(&self) -> *mut u892     pub fn as_mut_ptr(&self) -> *mut u8 {
93         self.buf.buf as *mut u8
94     }
95 
96     /// Converts a slice of `IoBufMut`s into a slice of `iovec`s.
97     #[inline]
as_iobufs<'slice>(iovs: &'slice [IoBufMut<'_>]) -> &'slice [IoBuf]98     pub fn as_iobufs<'slice>(iovs: &'slice [IoBufMut<'_>]) -> &'slice [IoBuf] {
99         // Safe because `IoBufMut` is ABI-compatible with `WSABUF`.
100         unsafe { slice::from_raw_parts(iovs.as_ptr() as *const WSABUF, iovs.len()) }
101     }
102 }
103 
104 impl<'a> AsRef<WSABUF> for IoBufMut<'a> {
as_ref(&self) -> &WSABUF105     fn as_ref(&self) -> &WSABUF {
106         &self.buf
107     }
108 }
109 
110 impl<'a> AsMut<WSABUF> for IoBufMut<'a> {
as_mut(&mut self) -> &mut WSABUF111     fn as_mut(&mut self) -> &mut WSABUF {
112         &mut self.buf
113     }
114 }
115 
116 struct DebugWSABUF(WSABUF);
117 impl Debug for DebugWSABUF {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result118     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119         f.debug_struct("WSABUF")
120             .field("buf", &self.0.buf)
121             .field("len", &self.0.len)
122             .finish()
123     }
124 }
125 
126 impl<'a> Debug for IoBufMut<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result127     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128         f.debug_struct("IoBufMut")
129             .field("buf", &DebugWSABUF(self.buf))
130             .field("phantom", &self.phantom)
131             .finish()
132     }
133 }
134