use bytes::{BufMut, Bytes, BytesMut};
use monocoque_core::options::SocketOptions;
use monocoque_core::rt::TcpStream;
use std::io;
use tracing::debug;
pub const FLAG_LONG: u8 = 0x02;
pub const FLAG_COMMAND: u8 = 0x04;
pub fn encode_frame(flags: u8, body: &Bytes) -> Bytes {
let len = body.len();
let header_len = if len <= 255 { 2 } else { 9 };
let mut out = BytesMut::with_capacity(header_len + len);
if len <= 255 {
out.put_u8(flags & !FLAG_LONG);
out.put_u8(len as u8);
} else {
out.put_u8(flags | FLAG_LONG);
out.put_u64(len as u64);
}
out.extend_from_slice(body);
out.freeze()
}
pub fn build_ready(socket_type: &str, identity: Option<&[u8]>) -> Bytes {
let mut body = BytesMut::new();
body.put_u8(5);
body.extend_from_slice(b"READY");
put_property(&mut body, "Socket-Type", socket_type.as_bytes());
if let Some(id) = identity {
put_property(&mut body, "Identity", id);
}
body.freeze()
}
#[inline]
fn put_property(dst: &mut BytesMut, name: &str, value: &[u8]) {
let name_bytes = name.as_bytes();
dst.put_u8(name_bytes.len() as u8);
dst.extend_from_slice(name_bytes);
dst.put_u32(value.len() as u32);
dst.extend_from_slice(value);
}
pub fn configure_tcp_stream(
stream: &TcpStream,
options: &SocketOptions,
socket_name: &str,
) -> io::Result<()> {
monocoque_core::tcp::enable_tcp_nodelay(stream)?;
debug!("[{}] TCP_NODELAY enabled", socket_name);
monocoque_core::tcp::configure_tcp_keepalive(
stream,
options.tcp_keepalive,
options.tcp_keepalive_cnt,
options.tcp_keepalive_idle,
options.tcp_keepalive_intvl,
)?;
if options.tcp_keepalive == 1 {
debug!(
"[{}] TCP keepalive enabled (cnt={}, idle={}s, intvl={}s)",
socket_name,
options.tcp_keepalive_cnt,
options.tcp_keepalive_idle,
options.tcp_keepalive_intvl
);
}
Ok(())
}