use std::sync::Arc;
use crate::{
metadata::{
customattributes::CustomAttributeValueList,
signatures::{
parse_field_signature, parse_local_var_signature, parse_method_signature,
CALLING_CONVENTION, SIGNATURE_HEADER,
},
streams::Blob,
tables::{StandAloneSig, StandAloneSigRc, StandAloneSignature},
tables::{TableInfoRef, TableRow},
token::Token,
},
Result,
};
#[derive(Clone, Debug)]
pub struct StandAloneSigRaw {
pub rid: u32,
pub token: Token,
pub offset: usize,
pub signature: u32,
}
impl StandAloneSigRaw {
pub fn to_owned(&self, blob: &Blob) -> Result<StandAloneSigRc> {
let sig_data = blob.get(self.signature as usize)?;
if sig_data.is_empty() {
return Err(malformed_error!(
"StandAloneSig blob is empty at index {}",
self.signature
));
}
let first_byte = sig_data[0];
let parsed_signature = match first_byte {
SIGNATURE_HEADER::LOCAL_SIG => {
let locals = parse_local_var_signature(sig_data)?;
StandAloneSignature::LocalVariables(locals)
}
SIGNATURE_HEADER::FIELD => {
let field = parse_field_signature(sig_data)?;
StandAloneSignature::Field(field)
}
_ => {
let calling_conv = first_byte & CALLING_CONVENTION::KIND_MASK;
if calling_conv <= CALLING_CONVENTION::VARARG {
let method = parse_method_signature(sig_data)?;
StandAloneSignature::Method(method)
} else {
return Err(malformed_error!(
"Unknown StandAloneSig signature type: 0x{:02X}",
first_byte
));
}
}
};
Ok(Arc::new(StandAloneSig {
rid: self.rid,
token: self.token,
offset: self.offset,
signature: self.signature,
custom_attributes: CustomAttributeValueList::default(),
parsed_signature,
}))
}
pub fn apply(&self) -> Result<()> {
Ok(())
}
}
impl TableRow for StandAloneSigRaw {
#[rustfmt::skip]
fn row_size(sizes: &TableInfoRef) -> u32 {
u32::from(
sizes.blob_bytes()
)
}
}