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