use super::{CommsEnvError, CommsEnvErrorRepr};
pub struct CommsInRaw {
handle: windows_sys::Win32::Foundation::HANDLE,
}
pub struct CommsOutRaw {
handle: windows_sys::Win32::Foundation::HANDLE,
}
unsafe impl Send for CommsInRaw {
}
unsafe impl Send for CommsOutRaw {
}
impl CommsInRaw {
pub fn from_env() -> Result<CommsInRaw, CommsEnvError> {
Ok(CommsInRaw {
handle: env_var_handle("FLEETSPEAK_COMMS_CHANNEL_INFD")?,
})
}
}
impl CommsOutRaw {
pub fn from_env() -> Result<CommsOutRaw, CommsEnvError> {
Ok(CommsOutRaw {
handle: env_var_handle("FLEETSPEAK_COMMS_CHANNEL_OUTFD")?,
})
}
}
impl std::io::Read for CommsInRaw {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let buf_len = u32::try_from(buf.len())
.map_err(|_| std::io::ErrorKind::InvalidInput)?;
let mut count = std::mem::MaybeUninit::uninit();
let status = unsafe {
windows_sys::Win32::Storage::FileSystem::ReadFile(
self.handle,
buf.as_mut_ptr(),
buf_len,
count.as_mut_ptr(),
std::ptr::null_mut(),
)
};
if status == windows_sys::Win32::Foundation::FALSE {
return Err(std::io::Error::last_os_error());
}
let count = unsafe { count.assume_init() };
Ok(count as usize)
}
}
impl std::io::Write for CommsOutRaw {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let buf_len = u32::try_from(buf.len())
.map_err(|_| std::io::ErrorKind::InvalidInput)?;
let mut count = std::mem::MaybeUninit::uninit();
let status = unsafe {
windows_sys::Win32::Storage::FileSystem::WriteFile(
self.handle,
buf.as_ptr(),
buf_len,
count.as_mut_ptr(),
std::ptr::null_mut(),
)
};
if status == windows_sys::Win32::Foundation::FALSE {
return Err(std::io::Error::last_os_error());
}
let count = unsafe { count.assume_init() };
Ok(count as usize)
}
fn flush(&mut self) -> std::io::Result<()> {
let status = unsafe {
windows_sys::Win32::Storage::FileSystem::FlushFileBuffers(
self.handle,
)
};
if status == windows_sys::Win32::Foundation::FALSE {
return Err(std::io::Error::last_os_error());
};
Ok(())
}
}
fn env_var_handle<K>(key: K) -> Result<windows_sys::Win32::Foundation::HANDLE, CommsEnvError>
where
K: AsRef<std::ffi::OsStr>,
{
match std::env::var(key) {
Ok(string) => match string.parse::<usize>() {
Ok(handle) => Ok(handle as windows_sys::Win32::Foundation::HANDLE),
Err(_) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotParsable(string.into()),
}),
}
Err(std::env::VarError::NotPresent) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotSpecified,
}),
Err(std::env::VarError::NotUnicode(string)) => Err(CommsEnvError {
repr: CommsEnvErrorRepr::NotParsable(string),
}),
}
}