use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
use crate::desktop::ipc::MAX_FRAME_SIZE;
pub async fn read_frame<R: AsyncRead + Unpin>(reader: &mut R) -> Result<Option<Vec<u8>>, String> {
let mut len_buf = [0u8; 4];
match reader.read_exact(&mut len_buf).await {
Ok(_) => {}
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(None),
Err(e) => return Err(format!("read frame: {e}")),
}
let len = u32::from_be_bytes(len_buf) as usize;
if len > MAX_FRAME_SIZE {
return Err(format!("frame too large: {len}"));
}
if len == 0 {
return Err("zero-length frame".into());
}
let mut payload = vec![0u8; len];
reader
.read_exact(&mut payload)
.await
.map_err(|e| format!("read payload: {e}"))?;
Ok(Some(payload))
}
pub async fn write_frame<W: AsyncWrite + Unpin>(
writer: &mut W,
frame: &[u8],
) -> Result<(), String> {
writer
.write_all(frame)
.await
.map_err(|e| format!("write frame: {e}"))?;
Ok(())
}
#[cfg(unix)]
pub use crate::desktop::transport_unix::{
accept, bind, cleanup, connect, peer_cred_check, split, TransportListener, TransportReadHalf,
TransportStream, TransportWriteHalf,
};
#[cfg(windows)]
pub use crate::desktop::transport_windows::{
accept, bind, cleanup, connect, peer_cred_check, split, TransportListener, TransportReadHalf,
TransportStream, TransportWriteHalf,
};