//! Incoming/Outgoing frame utilities.
use educe::Educe;
use libthreema_macros::Name;
use crate::utils::{debug::debug_slice_length, frame::VariableLengthFrameDecoderU32LittleEndianDelimited};
const HEADER_LENGTH: usize = 4;
/// An incoming frame.
#[derive(Educe)]
#[educe(Debug)]
pub struct RendezvousIncomingFrame(#[educe(Debug(method(debug_slice_length)))] pub Vec<u8>);
/// Incoming frame decoder.
pub(super) type FrameDecoder = VariableLengthFrameDecoderU32LittleEndianDelimited;
impl FrameDecoder {
// During the handshake and before nomination, we don't expect frames larger than 16 KiB. After
// the handshake, we don't expect frames larger than 100 MiB. (If we ever need larger frames
// than this, we need to add Blob chunking and stream the content.)
pub(super) const MAX_LENGTH_AFTER_NOMINATION: usize = 100 * 1_048_576;
pub(super) const MAX_LENGTH_BEFORE_NOMINATION: usize = 16_384;
}
/// An outgoing frame.
///
/// TODO(LIB-30): Simplify.
#[derive(Educe, Name)]
#[educe(Debug)]
pub struct RendezvousOutgoingFrame(#[educe(Debug(method(debug_slice_length)))] pub(super) Vec<u8>);
impl RendezvousOutgoingFrame {
/// Encode the frame to bytes (header bytes, followed by the payload).
///
/// # Panics
///
/// Will panic if the enclosed frame's length exceeds a u32.
#[must_use]
pub fn encode(&self) -> ([u8; HEADER_LENGTH], &[u8]) {
// Encode the length
let length = u32::try_from(self.0.len())
.expect("Frame length must be <= 2^32-1")
.to_le_bytes();
// Yield slice of the payload
let payload = &self.0;
(length, payload)
}
}
impl From<RendezvousOutgoingFrame> for Vec<u8> {
fn from(frame: RendezvousOutgoingFrame) -> Self {
let (header, payload) = frame.encode();
[header.as_slice(), payload].concat()
}
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland