rsbx 2.0.0

Enhanced implementation of SeqBox in Rust
Documentation
use reed_solomon_erasure::ReedSolomon;
use smallvec::SmallVec;
use sbx_block;
use sbx_specs::{Version,
                SBX_LARGEST_BLOCK_SIZE,
                ver_to_block_size,
                ver_uses_rs};

pub struct RSEncoder {
    index    : usize,
    rs_codec : ReedSolomon,
    version  : Version,
    par_buf  : SmallVec<[SmallVec<[u8; SBX_LARGEST_BLOCK_SIZE]>; 32]>,
    active   : bool,
}

macro_rules! mark_active {
    (
        $self:ident
    ) => {{
        $self.active = true;
    }}
}

macro_rules! mark_inactive {
    (
        $self:ident
    ) => {{
        $self.active = false;
    }}
}

macro_rules! incre_index {
    (
        $self:ident
    ) => {{
        $self.index += 1;
    }}
}

macro_rules! reset_index {
    (
        $self:ident
    ) => {{
        $self.index = 0;
    }}
}

macro_rules! codec_ready {
    (
        $self:ident
    ) => {{
        $self.index == $self.rs_codec.data_shard_count()
    }}
}

impl RSEncoder {
    pub fn new(version       : Version,
               data_shards   : usize,
               parity_shards : usize) -> RSEncoder {
        assert!(ver_uses_rs(version));

        let block_size = ver_to_block_size(version);

        let par_buf : SmallVec<[SmallVec<[u8; SBX_LARGEST_BLOCK_SIZE]>; 32]> =
            smallvec![smallvec![0; block_size]; parity_shards];

        RSEncoder {
            index    : 0,
            rs_codec : ReedSolomon::new(data_shards,
                                        parity_shards).unwrap(),
            version,
            par_buf,
            active : false,
        }
    }

    pub fn active(&self) -> bool {
        self.active
    }

    pub fn unfilled_slot_count(&self) -> usize {
        self.total_slot_count() - self.index
    }

    pub fn total_slot_count(&self) -> usize {
        self.rs_codec.data_shard_count()
    }

    pub fn encode_no_block_sync(&mut self,
                                data : &[u8])
                                -> Option<&mut SmallVec<[SmallVec<[u8; SBX_LARGEST_BLOCK_SIZE]>; 32]>> {
        let data = sbx_block::slice_data_buf(self.version, data);

        let version  = self.version;
        let rs_codec = &self.rs_codec;
        let par_buf  = &mut self.par_buf;

        {
            let mut parity : SmallVec<[&mut [u8]; 32]> =
                SmallVec::with_capacity(par_buf.len());

            for p in par_buf.iter_mut() {
                parity.push(sbx_block::slice_data_buf_mut(version, p));
            }
            rs_codec.encode_single_sep(self.index,
                                       data,
                                       &mut parity).unwrap();
        }

        incre_index!(self);

        if codec_ready!(self) {
            reset_index!(self);
            mark_inactive!(self);
            Some(par_buf)
        } else {
            mark_active!(self);
            None
        }
    }
}