use crate::{dir::*, error::*, impl_from_bytes, mem::*};
use core::mem;
pub struct Certificate<'a> {
head: &'a CertificateHead,
data: ByteReader<'a>,
}
impl<'a> Certificate<'a> {
pub fn new(bytes: &'a [u8], head: &'a CertificateHead) -> Self {
Self {
data: ByteReader::new(bytes),
head,
}
}
pub fn revision(&self) -> u16 {
self.head.revision
}
pub fn typ(&self) -> u16 {
self.head.typ
}
pub fn value(&self) -> &ByteReader<'a> {
&self.data
}
}
pub struct CertificateTable<'a> {
data: ByteReader<'a>,
}
impl<'a> Iterator for CertificateTable<'a> {
type Item = Result<Certificate<'a>>;
fn next(&mut self) -> Option<Self::Item> {
match self.data.read::<CertificateHead>() {
Ok(head) => {
let data = &self.data.remaining_bytes()
[..head.length as usize - mem::size_of::<CertificateHead>()];
self.data.skip_to(Pos::Rel(
algin_up(head.length as _, 8)
- mem::size_of::<CertificateHead>(),
));
Some(Ok(Certificate::new(data, head)))
}
Err(Error::InsufficientBuffer) => None,
Err(e) => Some(Err(e)),
}
}
}
impl<'a> DataDirectoryTable<'a> for CertificateTable<'a> {
fn new(bytes: &'a [u8], _dir: &'a DataDirectory) -> Self {
Self {
data: ByteReader::new(bytes),
}
}
fn typ() -> DataDirectoryType {
DataDirectoryType::CertificateTable
}
}
#[derive(Clone, Copy)]
#[repr(C)]
pub struct CertificateHead {
length: u32,
revision: u16,
typ: u16,
}
impl_from_bytes!(CertificateHead);