use crate::raw;
use std::{marker, mem};
pub trait Param {
fn to_raw(&mut self) -> raw::TEEC_Parameter;
fn param_type(&self) -> ParamType;
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self;
}
pub struct ParamValue {
raw: raw::TEEC_Value,
param_type: ParamType,
}
impl ParamValue {
pub fn new(a: u32, b: u32, param_type: ParamType) -> Self {
let raw = raw::TEEC_Value { a, b };
Self { raw, param_type }
}
pub fn a(&self) -> u32 {
self.raw.a
}
pub fn b(&self) -> u32 {
self.raw.b
}
}
impl Param for ParamValue {
fn to_raw(&mut self) -> raw::TEEC_Parameter {
raw::TEEC_Parameter { value: self.raw }
}
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
Self {
raw: unsafe { raw.value },
param_type,
}
}
fn param_type(&self) -> ParamType {
self.param_type
}
}
pub struct ParamNone;
impl Param for ParamNone {
fn to_raw(&mut self) -> raw::TEEC_Parameter {
let raw: raw::TEEC_Parameter = unsafe { mem::zeroed() };
raw
}
fn param_type(&self) -> ParamType {
ParamType::None
}
fn from_raw(_raw: raw::TEEC_Parameter, _param_type: ParamType) -> Self {
Self
}
}
pub struct ParamTmpRef<'a> {
raw: raw::TEEC_TempMemoryReference,
param_type: ParamType,
_marker: marker::PhantomData<&'a mut [u8]>,
}
impl<'a> ParamTmpRef<'a> {
pub fn new_input(buffer: &'a [u8]) -> Self {
let raw = raw::TEEC_TempMemoryReference {
buffer: buffer.as_ptr() as _,
size: buffer.len(),
};
Self {
raw,
param_type: ParamType::MemrefTempInput,
_marker: marker::PhantomData,
}
}
pub fn new_output(buffer: &'a mut [u8]) -> Self {
let raw = raw::TEEC_TempMemoryReference {
buffer: buffer.as_ptr() as _,
size: buffer.len(),
};
Self {
raw,
param_type: ParamType::MemrefTempOutput,
_marker: marker::PhantomData,
}
}
pub fn updated_size(&self) -> usize {
self.raw.size
}
}
impl<'a> Param for ParamTmpRef<'a> {
fn to_raw(&mut self) -> raw::TEEC_Parameter {
raw::TEEC_Parameter { tmpref: self.raw }
}
fn param_type(&self) -> ParamType {
self.param_type
}
fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
Self {
raw: unsafe { raw.tmpref },
param_type,
_marker: marker::PhantomData,
}
}
}
#[derive(Copy, Clone)]
pub enum ParamType {
None = 0,
ValueInput = 1,
ValueOutput = 2,
ValueInout = 3,
MemrefTempInput = 5,
MemrefTempOutput = 6,
MemrefTempInout = 7,
MemrefWhole = 0xC,
MemrefPartialInput = 0xD,
MemrefPartialOutput = 0xE,
MemrefPartialInout = 0xF,
}
impl From<u32> for ParamType {
fn from(value: u32) -> Self {
match value {
0 => ParamType::None,
1 => ParamType::ValueInput,
2 => ParamType::ValueOutput,
3 => ParamType::ValueInout,
5 => ParamType::MemrefTempInput,
6 => ParamType::MemrefTempOutput,
7 => ParamType::MemrefTempInout,
0xC => ParamType::MemrefWhole,
0xD => ParamType::MemrefPartialInput,
0xE => ParamType::MemrefPartialOutput,
0xF => ParamType::MemrefPartialInout,
_ => ParamType::None,
}
}
}
pub struct ParamTypes(u32);
impl ParamTypes {
pub fn new(p0: ParamType, p1: ParamType, p2: ParamType, p3: ParamType) -> Self {
ParamTypes((p0 as u32) | (p1 as u32) << 4 | (p2 as u32) << 8 | (p3 as u32) << 12)
}
pub fn into_flags(&self) -> (ParamType, ParamType, ParamType, ParamType) {
(
(0x000fu32 & self.0).into(),
(0x00f0u32 & self.0).into(),
(0x0f00u32 & self.0).into(),
(0xf000u32 & self.0).into(),
)
}
}
impl From<u32> for ParamTypes {
fn from(value: u32) -> Self {
ParamTypes(value)
}
}
impl From<[u32; 4]> for ParamTypes {
fn from(param_types: [u32; 4]) -> Self {
ParamTypes(
param_types[0] | param_types[1] << 4 | param_types[2] << 8 | param_types[3] << 12,
)
}
}
impl From<ParamTypes> for u32 {
fn from(a: ParamTypes) -> u32 {
a.0
}
}