use super::{
super::{DigitalSignature, DigitalSignatureFixed},
preview_u16_from_buf, validate_length, validate_length_fixed, DynamicSizeError, FixedSizeError, Parse, ParseExtend,
};
extern crate alloc;
use alloc::vec;
impl Parse for DigitalSignatureFixed {
type Error = FixedSizeError;
fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
where
Self: Sized,
{
let remaining = buf.remaining();
validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
Ok(Self {
header_signature: buf.get_u32_le(),
size_of_data: buf.get_u16_le(),
})
}
fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
let remaining = buf.remaining_mut();
validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
buf.put_u32_le(self.header_signature);
buf.put_u16_le(self.size_of_data);
Ok(())
}
}
impl ParseExtend for DigitalSignature {
type Error = DynamicSizeError;
type Fixed = DigitalSignatureFixed;
fn from_buf_fixed<T: bytes::Buf>(buf: &mut T, fixed: Self::Fixed) -> Result<Self, (Self::Error, Self::Fixed)>
where
Self: Sized,
{
let total = fixed.size_of_data as usize;
let fixed = validate_length_fixed(buf.remaining(), total, fixed, DynamicSizeError::UnsufficientExactBytes)?;
let mut signature_data = vec![0; fixed.size_of_data as usize];
buf.copy_to_slice(&mut signature_data);
Ok(Self { fixed, signature_data })
}
}
impl Parse for DigitalSignature {
type Error = DynamicSizeError;
fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
where
Self: Sized,
{
let remaining = buf.remaining();
const SIZE: usize = DigitalSignatureFixed::SIZE_IN_BYTES;
validate_length(remaining, SIZE, DynamicSizeError::UnsufficientAtLeastBytes)?;
const PEEK_START: usize = SIZE - 2;
let chunk = buf.chunk();
let size_of_data: u16 = preview_u16_from_buf(chunk, PEEK_START).ok_or(DynamicSizeError::NotContiguous(SIZE))?;
let total = SIZE + size_of_data as usize;
validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
let fixed = DigitalSignatureFixed::from_buf(buf).map_err(FixedSizeError::in_dynamic)?;
Self::from_buf_fixed(buf, fixed).map_err(|e| e.0)
}
fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
let remaining = buf.remaining_mut();
let total = DigitalSignatureFixed::SIZE_IN_BYTES + self.signature_data.len();
validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
self.fixed.to_buf(buf).map_err(FixedSizeError::in_dynamic)?;
buf.put_slice(&self.signature_data);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::{super::*, *};
#[test]
fn cycle_digital_signature() {
let signature_data = vec![48, 49, 32, 50];
let ds = DigitalSignature {
fixed: DigitalSignatureFixed {
header_signature: DigitalSignatureFixed::HEADER_SIGNATURE,
size_of_data: signature_data.len() as u16,
},
signature_data: signature_data.clone(),
};
let mut buf = vec![];
ds.to_buf(&mut buf).unwrap();
assert_eq!(buf.len(), DigitalSignatureFixed::SIZE_IN_BYTES + signature_data.len());
let mut readbuf = buf.as_slice();
let ds2 = DigitalSignature::from_buf(&mut readbuf).unwrap();
assert_eq!(ds, ds2);
assert_eq!(ds2.signature_data, signature_data);
}
#[test]
fn parseextend_digital_signature() {
let buf: Vec<u8> = vec![48, 49, 32, 50];
let mut fixed = DigitalSignatureFixed {
header_signature: DigitalSignatureFixed::HEADER_SIGNATURE,
size_of_data: buf.len() as u16,
};
assert!(DigitalSignature::from_buf_fixed(&mut buf.as_slice(), fixed.clone()).is_ok());
fixed.size_of_data += 1;
assert!(DigitalSignature::from_buf_fixed(&mut buf.as_slice(), fixed).is_err());
}
}