crcany-core 0.0.2

Core implementation of crcany library.
Documentation
use crate::crc::Crc;
use crate::model::bitwise::BitwiseModel;
use crate::spec::Spec;
use crate::util::{ones, reverse};

pub struct BytewiseModel {
    model: BitwiseModel,
    // table for byte-wise calculation
    pub table: [u128; 256],
}

impl BytewiseModel {
    pub fn reflect(&self) -> bool {
        self.model.reflect()
    }

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

    pub fn width(&self) -> u16 {
        self.model.width()
    }

    pub fn xorout(&self) -> u128 {
        self.model.xorout()
    }

    pub fn init(&self) -> u128 {
        self.model.init()
    }

    fn fill_table(&mut self) {
        for k in 0..256_usize {
            let byte = k as _;
            let mut crc = self.model.add_bytes(0, &[byte][..]);
            if self.model.reverse() {
                crc = reverse(crc, self.model.width());
            }
            if self.model.width() < 8 && !self.model.reflect() {
                crc <<= 8 - self.model.width();
            }
            self.table[k] = crc;
        }
    }

    pub fn from_spec(spec: Spec) -> BytewiseModel {
        let mut me = BytewiseModel {
            model: BitwiseModel::from_spec(spec),
            table: [0; 256],
        };
        me.fill_table();
        me
    }
}

impl Crc for BytewiseModel {
    type Int = u128;

    fn init(&self) -> u128 {
        self.init() as _
    }

    fn add_bytes(&self, mut crc: u128, bytes: &[u8]) -> u128 {
        if bytes.is_empty() {
            return crc;
        }

        if self.model.reverse() {
            crc = reverse(crc, self.model.width());
        }

        if self.model.reflect() {
            crc &= ones(self.model.width());
            for byte in bytes {
                crc = (crc >> 8) ^ self.table[(crc ^ (*byte as u128)) as u8 as usize];
            }
        } else if self.model.width() < 8 {
            let shift = 8 - self.model.width();
            crc <<= shift;
            for byte in bytes {
                crc = self.table[(crc ^ (*byte as u128)) as usize];
            }
            crc >>= shift;
        } else {
            let shift = self.model.width() - 8;
            for byte in bytes {
                crc = (crc << 8) ^ self.table[(((crc >> shift) ^ (*byte as u128)) as u8) as usize];
            }
            crc &= ones(self.model.width());
        }

        if self.model.reverse() {
            crc = reverse(crc, self.model.width());
        }

        crc as _
    }
}