use windows_sys::Win32::System::Pipes::{PIPE_SERVER_END, PIPE_TYPE_MESSAGE};
use super::*;
use crate::{
os::windows::{c_wrappers::duplicate_handle, limbo::LIMBO_ERR},
TryClone,
};
use std::mem::ManuallyDrop;
impl AsHandle for RawPipeStream {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.file_handle().as_handle()
}
}
derive_asraw!(RawPipeStream);
impl RawPipeStream {
fn from_handle_given_flags(handle: OwnedHandle, flags: u32) -> Self {
Self::new(
FileHandle::from(handle),
flags & PIPE_SERVER_END != 0,
NeedsFlushVal::Once,
)
}
}
fn is_server_check_failed_error(cause: io::Error, handle: OwnedHandle) -> FromHandleError {
FromHandleError {
details: FromHandleErrorKind::IsServerCheckFailed,
cause: Some(cause),
source: Some(handle),
}
}
impl TryFrom<OwnedHandle> for RawPipeStream {
type Error = FromHandleError;
fn try_from(handle: OwnedHandle) -> Result<Self, Self::Error> {
let flags = match c_wrappers::get_flags(handle.as_handle()) {
Ok(f) => f,
Err(e) => return Err(is_server_check_failed_error(e, handle)),
};
Ok(Self::from_handle_given_flags(handle, flags))
}
}
impl From<RawPipeStream> for OwnedHandle {
#[inline]
fn from(x: RawPipeStream) -> Self {
let x = ManuallyDrop::new(x);
let handle = unsafe { std::ptr::read(&x.handle) };
handle.expect(LIMBO_ERR).into()
}
}
impl<Rm: PipeModeTag, Sm: PipeModeTag> TryFrom<PipeStream<Rm, Sm>> for OwnedHandle {
type Error = PipeStream<Rm, Sm>;
#[inline]
fn try_from(s: PipeStream<Rm, Sm>) -> Result<Self, Self::Error> {
match s.raw {
MaybeArc::Inline(x) => Ok(x.into()),
MaybeArc::Shared(..) => Err(s),
}
}
}
impl<Rm: PipeModeTag, Sm: PipeModeTag> TryFrom<OwnedHandle> for PipeStream<Rm, Sm> {
type Error = FromHandleError;
fn try_from(handle: OwnedHandle) -> Result<Self, Self::Error> {
let flags = match c_wrappers::get_flags(handle.as_handle()) {
Ok(f) => f,
Err(e) => return Err(is_server_check_failed_error(e, handle)),
};
if Rm::MODE == Some(PipeMode::Messages) && flags & PIPE_TYPE_MESSAGE == 0 {
return Err(FromHandleError {
details: FromHandleErrorKind::NoMessageBoundaries,
cause: None,
source: Some(handle),
});
}
Ok(Self::new(RawPipeStream::from_handle_given_flags(
handle, flags,
)))
}
}
impl<Rm: PipeModeTag, Sm: PipeModeTag> TryClone for PipeStream<Rm, Sm> {
fn try_clone(&self) -> io::Result<Self> {
let handle = duplicate_handle(self.as_handle())?;
self.raw.needs_flush.on_clone();
let new = RawPipeStream::new(handle.into(), self.is_server(), NeedsFlushVal::Always);
Ok(Self::new(new))
}
}
impl<Rm: PipeModeTag, Sm: PipeModeTag> AsHandle for PipeStream<Rm, Sm> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.raw.as_handle()
}
}
derive_asraw!({Rm: PipeModeTag, Sm: PipeModeTag} PipeStream<Rm, Sm>, windows);