use std::io::{Cursor};
use crate::{
Result,
ValueEncoder,
ValueDecoder,
HeaderCoding,
HashType,
ZffError,
HEADER_IDENTIFIER_HASH_HEADER,
HEADER_IDENTIFIER_HASH_VALUE,
ERROR_HEADER_DECODER_UNKNOWN_HASH_TYPE,
};
#[derive(Debug,Clone)]
pub struct HashHeader {
version: u8,
hashes: Vec<HashValue>,
}
impl HashHeader {
pub fn new(version: u8, hashes: Vec<HashValue>) -> HashHeader {
Self {
version,
hashes,
}
}
pub fn hash_values(&self) -> &Vec<HashValue> {
&self.hashes
}
}
impl HeaderCoding for HashHeader {
type Item = HashHeader;
fn identifier() -> u32 {
HEADER_IDENTIFIER_HASH_HEADER
}
fn version(&self) -> u8 {
self.version
}
fn encode_header(&self) -> Vec<u8> {
let mut vec = vec![self.version];
vec.append(&mut self.hashes.encode_directly());
vec
}
fn encode_directly(&self) -> Vec<u8> {
let mut vec = Vec::new();
let mut encoded_header = self.encode_header();
let identifier = Self::identifier();
let encoded_header_length = 4 + 8 + (encoded_header.len() as u64); vec.append(&mut identifier.to_be_bytes().to_vec());
vec.append(&mut encoded_header_length.to_le_bytes().to_vec());
vec.append(&mut encoded_header);
vec
}
fn encode_for_key<K: Into<String>>(&self, key: K) -> Vec<u8> {
let mut vec = Vec::new();
let mut encoded_key = Self::encode_key(key);
vec.append(&mut encoded_key);
vec.append(&mut self.encode_directly());
vec
}
fn decode_content(data: Vec<u8>) -> Result<HashHeader> {
let mut cursor = Cursor::new(data);
let header_version = u8::decode_directly(&mut cursor)?;
let hashes = Vec::<HashValue>::decode_directly(&mut cursor)?;
Ok(HashHeader::new(header_version, hashes))
}
}
#[derive(Debug,Clone)]
pub struct HashValue {
version: u8,
hash_type: HashType,
hash: Vec<u8>,
}
impl HashValue {
pub fn new(version: u8, hash_type: HashType, hash: Vec<u8>) -> HashValue{
Self {
version,
hash_type,
hash
}
}
pub fn new_empty(structure_version: u8, hash_type: HashType) -> HashValue {
let hash_default_len = hash_type.default_len();
Self {
version: structure_version,
hash_type,
hash: vec!(0u8; hash_default_len/8),
}
}
pub fn hash_type(&self) -> &HashType {
&self.hash_type
}
pub fn set_hash(&mut self, hash: Vec<u8>) {
self.hash = hash
}
pub fn hash(&self) -> &Vec<u8> {
&self.hash
}
}
impl HeaderCoding for HashValue {
type Item = HashValue;
fn identifier() -> u32 {
HEADER_IDENTIFIER_HASH_VALUE
}
fn version(&self) -> u8 {
self.version
}
fn encode_header(&self) -> Vec<u8> {
let mut vec = vec![self.version, self.hash_type.clone() as u8];
vec.append(&mut self.hash.encode_directly());
vec
}
fn decode_content(data: Vec<u8>) -> Result<HashValue> {
let mut cursor = Cursor::new(data);
let structure_version = u8::decode_directly(&mut cursor)?;
let hash_type = match u8::decode_directly(&mut cursor)? {
0 => HashType::Blake2b512,
1 => HashType::SHA256,
2 => HashType::SHA512,
3 => HashType::SHA3_256,
_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_HASH_TYPE)),
};
let hash = Vec::<u8>::decode_directly(&mut cursor)?;
Ok(HashValue::new(structure_version, hash_type, hash))
}
}