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