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