1use crate::{build_tpm2b, parse_tpm2b, TpmBuild, TpmErrorKind, TpmParse, TpmResult, TpmSized};
6use core::{convert::TryFrom, fmt::Debug, mem::size_of, ops::Deref};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
9pub struct TpmBuffer<const CAPACITY: usize> {
10 bytes: [u8; CAPACITY],
11 len: usize,
12}
13
14impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
15 #[must_use]
16 pub const fn new() -> Self {
17 Self {
18 bytes: [0; CAPACITY],
19 len: 0,
20 }
21 }
22}
23
24impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
25 type Target = [u8];
26
27 fn deref(&self) -> &Self::Target {
28 &self.bytes[..self.len]
29 }
30}
31
32impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
39 const SIZE: usize = size_of::<u16>() + CAPACITY;
40 fn len(&self) -> usize {
41 size_of::<u16>() + self.len
42 }
43}
44
45impl<const CAPACITY: usize> TpmBuild for TpmBuffer<CAPACITY> {
46 fn build(&self, writer: &mut crate::TpmWriter) -> TpmResult<()> {
47 build_tpm2b(writer, self)
48 }
49}
50
51impl<const CAPACITY: usize> TpmParse for TpmBuffer<CAPACITY> {
52 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
53 let (bytes, remainder) = parse_tpm2b(buf)?;
54 let buffer = Self::try_from(bytes)?;
55 Ok((buffer, remainder))
56 }
57}
58
59impl<const CAPACITY: usize> TryFrom<&[u8]> for TpmBuffer<CAPACITY> {
60 type Error = TpmErrorKind;
61
62 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
63 if slice.len() > CAPACITY {
64 return Err(TpmErrorKind::CapacityExceeded);
65 }
66 let mut buffer = Self::new();
67 buffer.bytes[..slice.len()].copy_from_slice(slice);
68 buffer.len = slice.len();
69 Ok(buffer)
70 }
71}
72
73impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
74 fn as_ref(&self) -> &[u8] {
75 &self.bytes[..self.len]
76 }
77}
78
79impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 write!(f, "TpmBuffer(")?;
82 for byte in self.iter() {
83 write!(f, "{byte:02X}")?;
84 }
85 write!(f, ")")
86 }
87}