use std::io::{Error, IoSlice, Read, Result, Write};
use libc::{c_void, size_t};
use crate::error::rustls_io_result;
pub type rustls_read_callback = Option<
unsafe extern "C" fn(
userdata: *mut c_void,
buf: *mut u8,
n: size_t,
out_n: *mut size_t,
) -> rustls_io_result,
>;
pub(crate) type ReadCallback = unsafe extern "C" fn(
userdata: *mut c_void,
buf: *mut u8,
n: size_t,
out_n: *mut size_t,
) -> rustls_io_result;
pub(crate) struct CallbackReader {
pub callback: ReadCallback,
pub userdata: *mut c_void,
}
impl Read for CallbackReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut out_n: usize = 0;
let cb = self.callback;
let result = unsafe { cb(self.userdata, buf.as_mut_ptr(), buf.len(), &mut out_n) };
match result.0 {
0 => Ok(out_n),
e => Err(Error::from_raw_os_error(e)),
}
}
}
pub type rustls_write_callback = Option<
unsafe extern "C" fn(
userdata: *mut c_void,
buf: *const u8,
n: size_t,
out_n: *mut size_t,
) -> rustls_io_result,
>;
pub(crate) type WriteCallback = unsafe extern "C" fn(
userdata: *mut c_void,
buf: *const u8,
n: size_t,
out_n: *mut size_t,
) -> rustls_io_result;
pub(crate) struct CallbackWriter {
pub callback: WriteCallback,
pub userdata: *mut c_void,
}
impl Write for CallbackWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let mut out_n: usize = 0;
let cb = self.callback;
let result = unsafe { cb(self.userdata, buf.as_ptr(), buf.len(), &mut out_n) };
match result.0 {
0 => Ok(out_n),
e => Err(Error::from_raw_os_error(e)),
}
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
pub struct rustls_iovec {
_private: [u8; 0],
}
pub type rustls_write_vectored_callback = Option<
unsafe extern "C" fn(
userdata: *mut c_void,
iov: *const rustls_iovec,
count: size_t,
out_n: *mut size_t,
) -> rustls_io_result,
>;
pub(crate) type VectoredWriteCallback = unsafe extern "C" fn(
userdata: *mut c_void,
iov: *const rustls_iovec,
count: size_t,
out_n: *mut size_t,
) -> rustls_io_result;
pub(crate) struct VectoredCallbackWriter {
pub callback: VectoredWriteCallback,
pub userdata: *mut c_void,
}
impl Write for VectoredCallbackWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.write_vectored(&[IoSlice::new(buf)])
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
let mut out_n: usize = 0;
let cb = self.callback;
let result = unsafe {
cb(
self.userdata,
bufs.as_ptr() as *const rustls_iovec,
bufs.len(),
&mut out_n,
)
};
match result.0 {
0 => Ok(out_n),
e => Err(Error::from_raw_os_error(e)),
}
}
}