1use crate::{tss2_esys::UINT32, Result};
4use std::convert::TryFrom;
5
6pub trait Marshall: Sized {
9 const BUFFER_SIZE: usize;
10 fn marshall(&self) -> Result<Vec<u8>> {
12 let mut buffer = vec![0; Self::BUFFER_SIZE];
13 let mut offset = 0;
14
15 self.marshall_offset(&mut buffer, &mut offset)?;
16
17 buffer.truncate(offset);
18
19 Ok(buffer)
20 }
21
22 fn marshall_offset(&self, _marshalled_data: &mut [u8], _offset: &mut usize) -> Result<()> {
26 unimplemented!();
27 }
28}
29
30pub trait UnMarshall: Sized {
33 fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
35 Self::unmarshall_offset(marshalled_data, &mut 0)
36 }
37
38 fn unmarshall_offset(_marshalled_data: &[u8], _offset: &mut usize) -> Result<Self> {
42 unimplemented!();
43 }
44}
45
46macro_rules! impl_marshall_trait {
49 ($native_type:ident, $tss_type:ident, $tss_mu_type:ident, $convert_expression:stmt, $( $ref_sign:tt )?) => {
50 paste::item! {
51 impl $crate::traits::Marshall for $native_type {
52 const BUFFER_SIZE: usize = ::std::mem::size_of::<$tss_type>();
53
54 fn marshall_offset(
55 &self,
56 marshalled_data: &mut [u8],
57 offset: &mut usize,
58 ) -> $crate::Result<()> {
59 let ffi_object = self.clone().$convert_expression;
60 let ffi_buffer_size = $crate::ffi::FfiSizeType::try_from(marshalled_data.len())?;
61 let mut ffi_offset = $crate::ffi::FfiSizeType::try_from(*offset)?;
62 $crate::ReturnCode::ensure_success(
63 unsafe {
64 $crate::tss2_esys::[< Tss2_MU_ $tss_mu_type _Marshal >](
65 $( $ref_sign )?ffi_object,
66 marshalled_data.as_mut_ptr(),
67 ffi_buffer_size.into(),
68 ffi_offset.as_mut_ptr(),
69 )
70 },
71 |ret| {
72 log::error!(
73 "Failed to marshall {}: {}",
74 std::stringify!($native_type),
75 ret
76 );
77 },
78 )?;
79 *offset = usize::try_from(ffi_offset)?;
80 Ok(())
81 }
82 }
83 }
84 };
85}
86
87macro_rules! impl_unmarshall_trait {
90 ($native_type:ident, $tss_type:ident, $tss_mu_type:ident, $convert_expression:expr) => {
91 paste::item! {
92 impl $crate::traits::UnMarshall for $native_type {
93 fn unmarshall_offset(marshalled_data: &[u8], offset: &mut usize) -> Result<Self> {
94 let mut dest = $tss_type::default();
95 let ffi_buffer_size = $crate::ffi::FfiSizeType::try_from(marshalled_data.len())?;
96 let mut ffi_offset = $crate::ffi::FfiSizeType::try_from(*offset)?;
97 crate::ReturnCode::ensure_success(
98 unsafe {
99 crate::tss2_esys::[ < Tss2_MU_ $tss_mu_type _Unmarshal >](
100 marshalled_data.as_ptr(),
101 ffi_buffer_size.into(),
102 ffi_offset.as_mut_ptr(),
103 &mut dest,
104 )
105 },
106 |ret| log::error!("Failed to unmarshal {}: {}", std::stringify!($native_type), ret),
107 )?;
108 *offset = usize::try_from(ffi_offset)?;
109 $convert_expression(dest)
110 }
111 }
112 }
113 };
114}
115
116macro_rules! impl_mu_aliases {
120 ($tss_type:ident) => {
121 $crate::traits::impl_marshall_trait!($tss_type, $tss_type, $tss_type, into(),);
122 $crate::traits::impl_unmarshall_trait!($tss_type, $tss_type, $tss_type, Ok);
123 };
124}
125
126macro_rules! impl_mu_simple {
130 ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => {
131 $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, into(),);
132 $crate::traits::impl_unmarshall_trait!(
133 $native_type,
134 $tss_type,
135 $tss_mu_type,
136 $native_type::try_from
137 );
138 };
139 ($native_type:ident, $tss_type:ident) => {
140 $crate::traits::impl_mu_simple!($native_type, $tss_type, $tss_type);
141 };
142}
143
144macro_rules! impl_mu_standard {
148 ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => {
149 $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, into(), &);
150 $crate::traits::impl_unmarshall_trait!(
151 $native_type,
152 $tss_type,
153 $tss_mu_type,
154 $native_type::try_from
155 );
156 };
157 ($native_type:ident, $tss_type:ident) => {
158 $crate::traits::impl_mu_standard!($native_type, $tss_type, $tss_type);
159 };
160}
161
162macro_rules! impl_mu_complex {
166 ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => {
167 $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, try_into()?, &);
168 $crate::traits::impl_unmarshall_trait!(
169 $native_type,
170 $tss_type,
171 $tss_mu_type,
172 $native_type::try_from
173 );
174 };
175 ($native_type:ident, $tss_type:ident) => {
176 $crate::traits::impl_mu_complex!($native_type, $tss_type, $tss_type);
177 };
178}
179
180pub(crate) use impl_marshall_trait;
182pub(crate) use impl_mu_complex;
183pub(crate) use impl_mu_simple;
184pub(crate) use impl_mu_standard;
185pub(crate) use impl_unmarshall_trait;
186impl_mu_aliases!(UINT32);