use crate::{
common::RLNCError,
matrix::Matrix,
primitives::{ChunksError, field::Field, packet::RLNCPacket},
};
#[derive(Debug)]
pub struct Decoder<F: Field> {
chunk_size: usize,
chunk_count: usize,
matrix: Matrix<F>,
}
impl<F: Field> Decoder<F> {
pub fn new(chunk_size: usize, chunk_count: usize) -> Result<Self, RLNCError> {
if chunk_size == 0 {
return Err(ChunksError::ZeroChunkSize.into());
}
if chunk_count == 0 {
return Err(RLNCError::ZeroPacketCount);
}
Ok(Self { chunk_size, chunk_count, matrix: Matrix::new(chunk_count) })
}
pub fn decode(&mut self, packet: RLNCPacket<F>) -> Result<Option<Vec<u8>>, RLNCError> {
if packet.coding_vector.len() != self.chunk_count {
return Err(RLNCError::InvalidCodingVectorLength(
packet.coding_vector.len(),
self.chunk_count,
));
}
if self.matrix.push_rref(packet) {
return Ok(Some(self.matrix.decode(self.chunk_size)?));
}
Ok(None)
}
#[inline]
pub const fn rank(&self) -> usize {
self.matrix.rank()
}
#[inline]
pub const fn can_decode(&self) -> bool {
self.matrix.can_decode()
}
}