use crate::{
metadata::tables::{
assemblyref::AssemblyRefRaw,
types::{RowWritable, TableInfoRef},
},
utils::{write_le_at, write_le_at_dyn},
Result,
};
impl RowWritable for AssemblyRefRaw {
fn row_write(
&self,
data: &mut [u8],
offset: &mut usize,
_rid: u32,
sizes: &TableInfoRef,
) -> Result<()> {
write_le_at(
data,
offset,
u16::try_from(self.major_version).map_err(|_| {
malformed_error!(
"AssemblyRef major version out of range: {}",
self.major_version
)
})?,
)?;
write_le_at(
data,
offset,
u16::try_from(self.minor_version).map_err(|_| {
malformed_error!(
"AssemblyRef minor version out of range: {}",
self.minor_version
)
})?,
)?;
write_le_at(
data,
offset,
u16::try_from(self.build_number).map_err(|_| {
malformed_error!(
"AssemblyRef build number out of range: {}",
self.build_number
)
})?,
)?;
write_le_at(
data,
offset,
u16::try_from(self.revision_number).map_err(|_| {
malformed_error!(
"AssemblyRef revision number out of range: {}",
self.revision_number
)
})?,
)?;
write_le_at(data, offset, self.flags)?;
write_le_at_dyn(
data,
offset,
self.public_key_or_token,
sizes.is_large_blob(),
)?;
write_le_at_dyn(data, offset, self.name, sizes.is_large_str())?;
write_le_at_dyn(data, offset, self.culture, sizes.is_large_str())?;
write_le_at_dyn(data, offset, self.hash_value, sizes.is_large_blob())?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::metadata::{
tables::types::{RowReadable, TableId, TableInfo, TableRow},
token::Token,
};
#[test]
fn test_round_trip_serialization_short() {
let original_row = AssemblyRefRaw {
rid: 1,
token: Token::new(0x23000001),
offset: 0,
major_version: 0x0101,
minor_version: 0x0202,
build_number: 0x0303,
revision_number: 0x0404,
flags: 0x05050505,
public_key_or_token: 0x0606,
name: 0x0707,
culture: 0x0808,
hash_value: 0x0909,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(TableId::AssemblyRef, 1)],
false,
false,
false,
));
let row_size = <AssemblyRefRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row = AssemblyRefRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(original_row.major_version, deserialized_row.major_version);
assert_eq!(original_row.minor_version, deserialized_row.minor_version);
assert_eq!(original_row.build_number, deserialized_row.build_number);
assert_eq!(
original_row.revision_number,
deserialized_row.revision_number
);
assert_eq!(original_row.flags, deserialized_row.flags);
assert_eq!(
original_row.public_key_or_token,
deserialized_row.public_key_or_token
);
assert_eq!(original_row.name, deserialized_row.name);
assert_eq!(original_row.culture, deserialized_row.culture);
assert_eq!(original_row.hash_value, deserialized_row.hash_value);
assert_eq!(offset, row_size, "Offset should match expected row size");
}
#[test]
fn test_round_trip_serialization_long() {
let original_row = AssemblyRefRaw {
rid: 1,
token: Token::new(0x23000001),
offset: 0,
major_version: 0x0101,
minor_version: 0x0202,
build_number: 0x0303,
revision_number: 0x0404,
flags: 0x05050505,
public_key_or_token: 0x06060606,
name: 0x07070707,
culture: 0x08080808,
hash_value: 0x09090909,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(TableId::AssemblyRef, 1)],
true,
true,
true,
));
let row_size = <AssemblyRefRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row = AssemblyRefRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(original_row.major_version, deserialized_row.major_version);
assert_eq!(original_row.minor_version, deserialized_row.minor_version);
assert_eq!(original_row.build_number, deserialized_row.build_number);
assert_eq!(
original_row.revision_number,
deserialized_row.revision_number
);
assert_eq!(original_row.flags, deserialized_row.flags);
assert_eq!(
original_row.public_key_or_token,
deserialized_row.public_key_or_token
);
assert_eq!(original_row.name, deserialized_row.name);
assert_eq!(original_row.culture, deserialized_row.culture);
assert_eq!(original_row.hash_value, deserialized_row.hash_value);
assert_eq!(offset, row_size, "Offset should match expected row size");
}
#[test]
fn test_known_binary_format_short() {
let expected_data = vec![
0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, ];
let row = AssemblyRefRaw {
rid: 1,
token: Token::new(0x23000001),
offset: 0,
major_version: 0x0101,
minor_version: 0x0202,
build_number: 0x0303,
revision_number: 0x0404,
flags: 0x05050505,
public_key_or_token: 0x0606,
name: 0x0707,
culture: 0x0808,
hash_value: 0x0909,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(TableId::AssemblyRef, 1)],
false,
false,
false,
));
let row_size = <AssemblyRefRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
row.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
assert_eq!(
buffer, expected_data,
"Generated binary should match expected format"
);
assert_eq!(
offset,
expected_data.len(),
"Offset should match data length"
);
}
#[test]
fn test_known_binary_format_long() {
let expected_data = vec![
0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, ];
let row = AssemblyRefRaw {
rid: 1,
token: Token::new(0x23000001),
offset: 0,
major_version: 0x0101,
minor_version: 0x0202,
build_number: 0x0303,
revision_number: 0x0404,
flags: 0x05050505,
public_key_or_token: 0x06060606,
name: 0x07070707,
culture: 0x08080808,
hash_value: 0x09090909,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(TableId::AssemblyRef, 1)],
true,
true,
true,
));
let row_size = <AssemblyRefRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
row.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
assert_eq!(
buffer, expected_data,
"Generated binary should match expected format"
);
assert_eq!(
offset,
expected_data.len(),
"Offset should match data length"
);
}
}