You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
2.7 KiB

use crate::*;
use std::{
io::{
Read,
},
};
#[derive(Clone,Debug,PartialEq,Eq,Hash)]
pub enum Algorithm
{
Crc32,
Crc64,
Sha256,
}
impl Default for Algorithm
{
fn default() -> Self
{
Self::Crc64
}
}
#[derive(Clone,Debug,PartialEq,Eq,Hash)]
pub struct Context
{
algo: Algorithm,
salt: salt::Salt,
}
impl Context
{
pub fn new(algo: Algorithm, salt: impl Into<salt::Salt>) -> Self
{
Self {
algo,
salt: salt.into(),
}
}
pub fn get_algorithm(&self) -> &Algorithm
{
&self.algo
}
pub fn get_salt(&self) -> &salt::Salt
{
&self.salt
}
pub fn compute<R: Read>(&self, mut from: R) -> Result<(usize, Box<[u8]>), error::Error>
{
fn provide<P,R>(input: &mut R, salt: &salt::Salt, output: &mut usize) -> Result<Vec<u8>, error::Error>
where P: provider::ByteProvider,
R: Read + ?Sized
{
let this = P::compute(input, &salt, output)?;
Ok(Vec::from(this.bytes()))
}
let mut output = 0usize;
let bytes = match self.algo
{
Algorithm::Crc32 => provide::<hash::Crc32Checksum, _>(&mut from, &self.salt, &mut output)?,
Algorithm::Crc64 => provide::<hash::Crc64Checksum, _>(&mut from, &self.salt, &mut output)?,
Algorithm::Sha256 => provide::<hash::Sha256Hash, _>(&mut from, &self.salt, &mut output)?,
}.into_boxed_slice();
Ok((output, bytes))
}
pub unsafe fn into_raw(self) -> CContext
{
CContext{
algo: u8::from(self.algo),
salt: salt::into_raw(self.salt),
}
}
pub unsafe fn clone_from_raw(from: *const CContext) -> Self
{
let from = &*from;
Self {
algo: from.algo.into(),
salt: salt::clone_from_raw(&from.salt as *const salt::FFI),
}
}
pub unsafe fn from_raw(from: *mut CContext) -> Self
{
let from = &mut *from;
let output = Self{
algo: from.algo.into(),
salt: salt::from_raw(&mut from.salt as *mut salt::FFI),
};
from.algo = 0;
output
}
}
impl Default for Context
{
fn default() -> Self
{
Self {
algo: Default::default(),
salt: Default::default(),
}
}
}
pub const ALGO_DEFAULT: u8 = 0;
pub const ALGO_CRC32: u8 = 1;
pub const ALGO_CRC64: u8 = 2;
pub const ALGO_SHA256: u8 = 3;
/// FFI context
#[derive(Debug)]
#[repr(C)]
pub struct CContext
{
algo: u8,
salt: salt::FFI,
}
impl From<Algorithm> for u8
{
fn from(al: Algorithm) -> Self
{
match al {
Algorithm::Crc32 => ALGO_CRC32,
Algorithm::Crc64 => ALGO_CRC64,
Algorithm::Sha256 => ALGO_SHA256,
}
}
}
impl From<u8> for Algorithm
{
fn from(al: u8) -> Self
{
match al {
ALGO_CRC32 => Algorithm::Crc32,
ALGO_CRC64 => Algorithm::Crc64,
ALGO_SHA256 => Algorithm::Sha256,
_ => Self::default(),
}
}
}