1 //! The following is derived from Rust's 2 //! library/std/src/sys/unix/io.rs 3 //! dca3f1b786efd27be3b325ed1e01e247aa589c3b. 4 //! 5 //! All code in this file is licensed MIT or Apache 2.0 at your option. 6 7 #![allow(unsafe_code)] 8 use crate::backend::c; 9 #[cfg(not(linux_raw))] 10 use c::size_t as __kernel_size_t; 11 use core::marker::PhantomData; 12 use core::slice; 13 #[cfg(linux_raw)] 14 use linux_raw_sys::general::__kernel_size_t; 15 16 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html> 17 #[derive(Copy, Clone)] 18 #[repr(transparent)] 19 pub struct IoSlice<'a> { 20 vec: c::iovec, 21 _p: PhantomData<&'a [u8]>, 22 } 23 24 impl<'a> IoSlice<'a> { 25 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.new> 26 #[inline] new(buf: &'a [u8]) -> IoSlice<'a>27 pub fn new(buf: &'a [u8]) -> IoSlice<'a> { 28 IoSlice { 29 vec: c::iovec { 30 iov_base: buf.as_ptr() as *mut u8 as *mut c::c_void, 31 iov_len: buf.len() as _, 32 }, 33 _p: PhantomData, 34 } 35 } 36 37 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance> 38 #[inline] advance(&mut self, n: usize)39 pub fn advance(&mut self, n: usize) { 40 if self.vec.iov_len < n as _ { 41 panic!("advancing IoSlice beyond its length"); 42 } 43 44 unsafe { 45 // `__kernel_size_t` will always have the same size as `usize`, but it is a `u32` on 46 // 32-bit platforms and `u64` on 64-bit platforms when using `linux_raw` backend 47 self.vec.iov_len -= n as __kernel_size_t; 48 self.vec.iov_base = self.vec.iov_base.add(n); 49 } 50 } 51 52 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.as_slice> 53 #[inline] as_slice(&self) -> &[u8]54 pub fn as_slice(&self) -> &[u8] { 55 unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } 56 } 57 } 58 59 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html> 60 #[repr(transparent)] 61 pub struct IoSliceMut<'a> { 62 vec: c::iovec, 63 _p: PhantomData<&'a mut [u8]>, 64 } 65 66 impl<'a> IoSliceMut<'a> { 67 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.new> 68 #[inline] new(buf: &'a mut [u8]) -> IoSliceMut<'a>69 pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { 70 IoSliceMut { 71 vec: c::iovec { 72 iov_base: buf.as_mut_ptr() as *mut c::c_void, 73 iov_len: buf.len() as _, 74 }, 75 _p: PhantomData, 76 } 77 } 78 79 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance> 80 #[inline] advance(&mut self, n: usize)81 pub fn advance(&mut self, n: usize) { 82 if self.vec.iov_len < n as _ { 83 panic!("advancing IoSliceMut beyond its length"); 84 } 85 86 unsafe { 87 // `__kernel_size_t` will always have the same size as `usize`, but it is a `u32` on 88 // 32-bit platforms and `u64` on 64-bit platforms when using `linux_raw` backend 89 self.vec.iov_len -= n as __kernel_size_t; 90 self.vec.iov_base = self.vec.iov_base.add(n); 91 } 92 } 93 94 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.as_slice> 95 #[inline] as_slice(&self) -> &[u8]96 pub fn as_slice(&self) -> &[u8] { 97 unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } 98 } 99 100 /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.as_slice_mut> 101 #[inline] as_mut_slice(&mut self) -> &mut [u8]102 pub fn as_mut_slice(&mut self) -> &mut [u8] { 103 unsafe { 104 slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) 105 } 106 } 107 } 108