summaryrefslogtreecommitdiffstats
path: root/third_party/rust/iovec/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/iovec/src/lib.rs161
-rw-r--r--third_party/rust/iovec/src/sys/mod.rs26
-rw-r--r--third_party/rust/iovec/src/sys/unix.rs52
-rw-r--r--third_party/rust/iovec/src/sys/unknown.rs57
-rw-r--r--third_party/rust/iovec/src/sys/windows.rs68
-rw-r--r--third_party/rust/iovec/src/unix.rs68
-rw-r--r--third_party/rust/iovec/src/windows.rs0
7 files changed, 432 insertions, 0 deletions
diff --git a/third_party/rust/iovec/src/lib.rs b/third_party/rust/iovec/src/lib.rs
new file mode 100644
index 0000000000..1e091a46c9
--- /dev/null
+++ b/third_party/rust/iovec/src/lib.rs
@@ -0,0 +1,161 @@
+//! A specialized byte slice type for performing vectored I/O operations.
+//!
+//! For more detail, see [`IoVec`] documentation.
+//!
+//! [`IoVec`]: struct.IoVec.html
+
+#[cfg(unix)]
+extern crate libc;
+
+mod sys;
+
+use std::{ops, mem};
+
+#[cfg(unix)]
+pub mod unix;
+
+/// Max length of an `IoVec` slice.
+///
+/// Attempts to convert slices longer than this value will result in a panic.
+pub const MAX_LENGTH: usize = sys::MAX_LENGTH;
+
+/// A specialized byte slice type for performing vectored I/O operations.
+///
+/// On all systems, the types needed to perform vectored I/O systems have the
+/// same size as Rust's [`slice`]. However, the layout is not necessarily the
+/// same. `IoVec` provides a portable compatibility layer.
+///
+/// The `IoVec` behaves like a Rust [`slice`], providing the same functions.
+/// It also provides conversion functions to and from the OS specific vectored
+/// types.
+///
+/// [`slice`]: https://doc.rust-lang.org/std/primitive.slice.html
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+///
+/// let mut data = vec![];
+/// data.extend_from_slice(b"hello");
+///
+/// let iovec: &IoVec = data.as_slice().into();
+///
+/// assert_eq!(&iovec[..], &b"hello"[..]);
+/// ```
+///
+/// # Panics
+///
+/// Attempting to convert a zero-length slice or a slice longer than
+/// [`MAX_LENGTH`] to an `IoVec` will result in a panic.
+///
+/// [`MAX_LENGTH`]: constant.MAX_LENGTH.html
+pub struct IoVec {
+ sys: sys::IoVec,
+}
+
+impl IoVec {
+ pub fn from_bytes(slice: &[u8]) -> Option<&IoVec> {
+ if slice.len() == 0 {
+ return None
+ }
+ unsafe {
+ let iovec: &sys::IoVec = slice.into();
+ Some(mem::transmute(iovec))
+ }
+ }
+
+ pub fn from_bytes_mut(slice: &mut [u8]) -> Option<&mut IoVec> {
+ if slice.len() == 0 {
+ return None
+ }
+ unsafe {
+ let iovec: &mut sys::IoVec = slice.into();
+ Some(mem::transmute(iovec))
+ }
+ }
+
+ #[deprecated(since = "0.1.0", note = "deref instead")]
+ #[doc(hidden)]
+ pub fn as_bytes(&self) -> &[u8] {
+ &**self
+ }
+
+ #[deprecated(since = "0.1.0", note = "deref instead")]
+ #[doc(hidden)]
+ pub fn as_mut_bytes(&mut self) -> &mut [u8] {
+ &mut **self
+ }
+}
+
+impl ops::Deref for IoVec {
+ type Target = [u8];
+
+ fn deref(&self) -> &[u8] {
+ &self.sys.as_ref()
+ }
+}
+
+impl ops::DerefMut for IoVec {
+ fn deref_mut(&mut self) -> &mut [u8] {
+ self.sys.as_mut()
+ }
+}
+
+#[doc(hidden)]
+impl<'a> From<&'a [u8]> for &'a IoVec {
+ fn from(bytes: &'a [u8]) -> &'a IoVec {
+ IoVec::from_bytes(bytes)
+ .expect("this crate accidentally accepted 0-sized slices \
+ originally but this was since discovered as a soundness \
+ hole, it's recommended to use the `from_bytes` \
+ function instead")
+ }
+}
+
+#[doc(hidden)]
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+ fn from(bytes: &'a mut [u8]) -> &'a mut IoVec {
+ IoVec::from_bytes_mut(bytes)
+ .expect("this crate accidentally accepted 0-sized slices \
+ originally but this was since discovered as a soundness \
+ hole, it's recommended to use the `from_bytes_mut` \
+ function instead")
+ }
+}
+
+#[doc(hidden)]
+impl<'a> Default for &'a IoVec {
+ fn default() -> Self {
+ panic!("this implementation was accidentally provided but is \
+ unfortunately unsound, it's recommended to stop using \
+ `IoVec::default` or construct a vector with a nonzero length");
+ }
+}
+
+#[doc(hidden)]
+impl<'a> Default for &'a mut IoVec {
+ fn default() -> Self {
+ panic!("this implementation was accidentally provided but is \
+ unfortunately unsound, it's recommended to stop using \
+ `IoVec::default` or construct a vector with a nonzero length");
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::IoVec;
+
+ #[test]
+ fn convert_ref() {
+ let buf: &IoVec = (&b"hello world"[..]).into();
+ assert_eq!(buf[..], b"hello world"[..]);
+ }
+
+ #[test]
+ fn convert_mut() {
+ let mut buf: Vec<u8> = b"hello world".to_vec();
+ let buf: &mut IoVec = (&mut buf[..]).into();
+ assert_eq!(buf[..], b"hello world"[..]);
+ }
+}
diff --git a/third_party/rust/iovec/src/sys/mod.rs b/third_party/rust/iovec/src/sys/mod.rs
new file mode 100644
index 0000000000..3e0efc99e8
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/mod.rs
@@ -0,0 +1,26 @@
+#[cfg(unix)]
+mod unix;
+
+#[cfg(unix)]
+pub use self::unix::{
+ IoVec,
+ MAX_LENGTH,
+};
+
+#[cfg(windows)]
+mod windows;
+
+#[cfg(windows)]
+pub use self::windows::{
+ IoVec,
+ MAX_LENGTH,
+};
+
+#[cfg(not(any(windows, unix)))]
+mod unknown;
+
+#[cfg(not(any(windows, unix)))]
+pub use self::unknown::{
+ IoVec,
+ MAX_LENGTH,
+};
diff --git a/third_party/rust/iovec/src/sys/unix.rs b/third_party/rust/iovec/src/sys/unix.rs
new file mode 100644
index 0000000000..4dbc0674f8
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/unix.rs
@@ -0,0 +1,52 @@
+use libc;
+use std::{mem, slice, usize};
+
+pub struct IoVec {
+ inner: [u8],
+}
+
+pub const MAX_LENGTH: usize = usize::MAX;
+
+impl IoVec {
+ pub fn as_ref(&self) -> &[u8] {
+ unsafe {
+ let vec = self.iovec();
+ slice::from_raw_parts(vec.iov_base as *const u8, vec.iov_len)
+ }
+ }
+
+ pub fn as_mut(&mut self) -> &mut [u8] {
+ unsafe {
+ let vec = self.iovec();
+ slice::from_raw_parts_mut(vec.iov_base as *mut u8, vec.iov_len)
+ }
+ }
+
+ unsafe fn iovec(&self) -> libc::iovec {
+ mem::transmute(&self.inner)
+ }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+ fn from(src: &'a [u8]) -> Self {
+ assert!(src.len() > 0);
+ unsafe {
+ mem::transmute(libc::iovec {
+ iov_base: src.as_ptr() as *mut _,
+ iov_len: src.len(),
+ })
+ }
+ }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+ fn from(src: &'a mut [u8]) -> Self {
+ assert!(src.len() > 0);
+ unsafe {
+ mem::transmute(libc::iovec {
+ iov_base: src.as_ptr() as *mut _,
+ iov_len: src.len(),
+ })
+ }
+ }
+}
diff --git a/third_party/rust/iovec/src/sys/unknown.rs b/third_party/rust/iovec/src/sys/unknown.rs
new file mode 100644
index 0000000000..37acedd78b
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/unknown.rs
@@ -0,0 +1,57 @@
+use std::{mem, slice, usize};
+
+#[derive(Clone)]
+pub struct WasmIoVec {
+ ptr: *const u8,
+ len: usize,
+}
+
+pub struct IoVec {
+ inner: [u8],
+}
+
+pub const MAX_LENGTH: usize = usize::MAX;
+
+impl IoVec {
+ pub fn as_ref(&self) -> &[u8] {
+ unsafe {
+ let vec = self.iovec();
+ slice::from_raw_parts(vec.ptr as *const u8, vec.len)
+ }
+ }
+
+ pub fn as_mut(&mut self) -> &mut [u8] {
+ unsafe {
+ let vec = self.iovec();
+ slice::from_raw_parts_mut(vec.ptr as *mut u8, vec.len)
+ }
+ }
+
+ unsafe fn iovec(&self) -> WasmIoVec {
+ mem::transmute(&self.inner)
+ }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+ fn from(src: &'a [u8]) -> Self {
+ assert!(src.len() > 0);
+ unsafe {
+ mem::transmute(WasmIoVec {
+ ptr: src.as_ptr() as *mut _,
+ len: src.len(),
+ })
+ }
+ }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+ fn from(src: &'a mut [u8]) -> Self {
+ assert!(src.len() > 0);
+ unsafe {
+ mem::transmute(WasmIoVec {
+ ptr: src.as_ptr() as *mut _,
+ len: src.len(),
+ })
+ }
+ }
+}
diff --git a/third_party/rust/iovec/src/sys/windows.rs b/third_party/rust/iovec/src/sys/windows.rs
new file mode 100644
index 0000000000..fc5b8fb427
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/windows.rs
@@ -0,0 +1,68 @@
+use std::{mem, slice, u32};
+
+// declare the types we need directly here to avoid bringing
+// in the old and slow winapi 0.2 dependency.
+
+type DWORD = u32;
+type ULONG = u32;
+type CHAR = i8;
+
+#[repr(C)]
+struct WSABUF {
+ pub len: ULONG,
+ pub buf: *mut CHAR,
+}
+
+pub struct IoVec {
+ inner: [u8],
+}
+
+pub const MAX_LENGTH: usize = u32::MAX as usize;
+
+impl IoVec {
+ pub fn as_ref(&self) -> &[u8] {
+ unsafe {
+ let vec = self.wsabuf();
+ slice::from_raw_parts(vec.buf as *const u8, vec.len as usize)
+ }
+ }
+
+ pub fn as_mut(&mut self) -> &mut [u8] {
+ unsafe {
+ let vec = self.wsabuf();
+ slice::from_raw_parts_mut(vec.buf as *mut u8, vec.len as usize)
+ }
+ }
+
+ unsafe fn wsabuf(&self) -> WSABUF {
+ mem::transmute(&self.inner)
+ }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+ fn from(src: &'a [u8]) -> Self {
+ assert!(src.len() > 0);
+ assert!(src.len() <= MAX_LENGTH);
+
+ unsafe {
+ mem::transmute(WSABUF {
+ buf: src.as_ptr() as *mut _,
+ len: src.len() as DWORD,
+ })
+ }
+ }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+ fn from(src: &'a mut [u8]) -> Self {
+ assert!(src.len() > 0);
+ assert!(src.len() <= MAX_LENGTH);
+
+ unsafe {
+ mem::transmute(WSABUF {
+ buf: src.as_ptr() as *mut _,
+ len: src.len() as DWORD,
+ })
+ }
+ }
+}
diff --git a/third_party/rust/iovec/src/unix.rs b/third_party/rust/iovec/src/unix.rs
new file mode 100644
index 0000000000..3ef3728bb0
--- /dev/null
+++ b/third_party/rust/iovec/src/unix.rs
@@ -0,0 +1,68 @@
+//! IoVec extensions for Unix platforms.
+//!
+//! These functions provide conversions to unix specific representations of the
+//! vectored data.
+//!
+//! # Examples
+//!
+//! ```
+//! use iovec::IoVec;
+//! use iovec::unix;
+//!
+//! let a = b"hello".to_vec();
+//! let b = b"world".to_vec();
+//!
+//! let bufs: &[&IoVec] = &[(&a[..]).into(), (&b[..]).into()];
+//! let os_bufs = unix::as_os_slice(&bufs[..]);
+//!
+//! // Use the `os_bufs` slice with `writev`.
+//! ```
+
+use IoVec;
+use libc;
+
+use std::mem;
+
+/// Convert a slice of `IoVec` refs to a slice of `libc::iovec`.
+///
+/// The return value can be passed to `writev` bindings.
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+/// use iovec::unix;
+///
+/// let a = b"hello".to_vec();
+/// let b = b"world".to_vec();
+///
+/// let bufs: &[&IoVec] = &[a[..].into(), b[..].into()];
+/// let os_bufs = unix::as_os_slice(bufs);
+///
+/// // Use the `os_bufs` slice with `writev`.
+/// ```
+pub fn as_os_slice<'a>(iov: &'a [&IoVec]) -> &'a [libc::iovec] {
+ unsafe { mem::transmute(iov) }
+}
+
+/// Convert a mutable slice of `IoVec` refs to a mutable slice of `libc::iovec`.
+///
+/// The return value can be passed to `readv` bindings.
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+/// use iovec::unix;
+///
+/// let mut a = [0; 10];
+/// let mut b = [0; 10];
+///
+/// let bufs: &mut [&mut IoVec] = &mut [(&mut a[..]).into(), (&mut b[..]).into()];
+/// let os_bufs = unix::as_os_slice_mut(bufs);
+///
+/// // Use the `os_bufs` slice with `readv`.
+/// ```
+pub fn as_os_slice_mut<'a>(iov: &'a mut [&mut IoVec]) -> &'a mut [libc::iovec] {
+ unsafe { mem::transmute(iov) }
+}
diff --git a/third_party/rust/iovec/src/windows.rs b/third_party/rust/iovec/src/windows.rs
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/third_party/rust/iovec/src/windows.rs