use crate::{
constants::{COMMAND_HEADER_LENGTH, FRAME_OVERHEAD_LENGTH, PRINT_TRANSFER_FRAME_OVERHEAD_LENGTH},
error::{EmapiError, Result},
};
pub const FILE_TRANSFER_CHUNK_HEADER_LENGTH: usize = 4;
pub const FILE_TRANSFER_PAYLOAD_ALIGNMENT: usize = 32;
pub fn print_transfer_payload_capacity(max_packet_length: usize) -> Result<usize> {
let Some(capacity) = max_packet_length.checked_sub(PRINT_TRANSFER_FRAME_OVERHEAD_LENGTH) else {
return Err(EmapiError::InvalidCapacity {
name: "print transfer payload",
});
};
if capacity == 0 {
return Err(EmapiError::InvalidCapacity {
name: "print transfer payload",
});
}
Ok(capacity)
}
pub fn file_transfer_payload_capacity(mtu: usize) -> Result<usize> {
let overhead = FRAME_OVERHEAD_LENGTH + COMMAND_HEADER_LENGTH + FILE_TRANSFER_CHUNK_HEADER_LENGTH;
let Some(capacity) = mtu.checked_sub(overhead) else {
return Err(EmapiError::InvalidCapacity {
name: "file transfer payload",
});
};
let aligned_capacity =
capacity / FILE_TRANSFER_PAYLOAD_ALIGNMENT * FILE_TRANSFER_PAYLOAD_ALIGNMENT;
if aligned_capacity == 0 {
return Err(EmapiError::InvalidCapacity {
name: "file transfer payload",
});
}
Ok(aligned_capacity)
}
pub fn chunk_print_data(data: &[u8], max_packet_length: usize) -> Result<Vec<Vec<u8>>> {
let payload_capacity = print_transfer_payload_capacity(max_packet_length)?;
let mut chunks = Vec::new();
for chunk in data.chunks(payload_capacity) {
chunks.push(chunk.to_vec());
}
Ok(chunks)
}