use crate::{
metadata::tables::{
module::ModuleRaw,
types::{RowWritable, TableInfoRef},
},
utils::{write_le_at, write_le_at_dyn},
Result,
};
impl RowWritable for ModuleRaw {
fn row_write(
&self,
data: &mut [u8],
offset: &mut usize,
_rid: u32,
sizes: &TableInfoRef,
) -> Result<()> {
write_le_at(
data,
offset,
u16::try_from(self.generation).map_err(|_| {
malformed_error!("Module generation out of range: {}", self.generation)
})?,
)?;
write_le_at_dyn(data, offset, self.name, sizes.is_large_str())?;
write_le_at_dyn(data, offset, self.mvid, sizes.is_large_guid())?;
write_le_at_dyn(data, offset, self.encid, sizes.is_large_guid())?;
write_le_at_dyn(data, offset, self.encbaseid, sizes.is_large_guid())?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::metadata::{
tables::types::{RowReadable, TableInfo, TableRow},
token::Token,
};
use std::sync::Arc;
#[test]
fn test_round_trip_serialization_small_heaps() {
let original_row = ModuleRaw {
rid: 1,
token: Token::new(0x00000001),
offset: 0,
generation: 0x0101,
name: 0x0202,
mvid: 0x0303,
encid: 0x0404,
encbaseid: 0x0505,
};
let table_info = TableInfo::new_test(&[], false, false, false);
let table_info_ref = Arc::new(table_info);
let row_size = <ModuleRaw as TableRow>::row_size(&table_info_ref) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 1, &table_info_ref)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row = ModuleRaw::row_read(&buffer, &mut read_offset, 1, &table_info_ref)
.expect("Deserialization should succeed");
assert_eq!(original_row.generation, deserialized_row.generation);
assert_eq!(original_row.name, deserialized_row.name);
assert_eq!(original_row.mvid, deserialized_row.mvid);
assert_eq!(original_row.encid, deserialized_row.encid);
assert_eq!(original_row.encbaseid, deserialized_row.encbaseid);
assert_eq!(offset, row_size, "Offset should match expected row size");
}
#[test]
fn test_round_trip_serialization_large_heaps() {
let original_row = ModuleRaw {
rid: 1,
token: Token::new(0x00000001),
offset: 0,
generation: 0x0101,
name: 0x02020202,
mvid: 0x03030303,
encid: 0x04040404,
encbaseid: 0x05050505,
};
let table_info = TableInfo::new_test(&[], true, true, true);
let table_info_ref = Arc::new(table_info);
let row_size = <ModuleRaw as TableRow>::row_size(&table_info_ref) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 1, &table_info_ref)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row = ModuleRaw::row_read(&buffer, &mut read_offset, 1, &table_info_ref)
.expect("Deserialization should succeed");
assert_eq!(original_row.generation, deserialized_row.generation);
assert_eq!(original_row.name, deserialized_row.name);
assert_eq!(original_row.mvid, deserialized_row.mvid);
assert_eq!(original_row.encid, deserialized_row.encid);
assert_eq!(original_row.encbaseid, deserialized_row.encbaseid);
assert_eq!(offset, row_size, "Offset should match expected row size");
}
#[test]
fn test_known_binary_format_small_heaps() {
let module_row = ModuleRaw {
rid: 1,
token: Token::new(0x00000001),
offset: 0,
generation: 0x0101,
name: 0x0202,
mvid: 0x0303,
encid: 0x0404,
encbaseid: 0x0505,
};
let table_info = TableInfo::new_test(&[], false, false, false);
let table_info_ref = Arc::new(table_info);
let mut buffer = vec![0u8; <ModuleRaw as TableRow>::row_size(&table_info_ref) as usize];
let mut offset = 0;
module_row
.row_write(&mut buffer, &mut offset, 1, &table_info_ref)
.expect("Serialization should succeed");
let expected = vec![
0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, ];
assert_eq!(
buffer, expected,
"Binary output should match expected format"
);
}
#[test]
fn test_known_binary_format_large_heaps() {
let module_row = ModuleRaw {
rid: 1,
token: Token::new(0x00000001),
offset: 0,
generation: 0x0101,
name: 0x02020202,
mvid: 0x03030303,
encid: 0x04040404,
encbaseid: 0x05050505,
};
let table_info = TableInfo::new_test(&[], true, true, true);
let table_info_ref = Arc::new(table_info);
let mut buffer = vec![0u8; <ModuleRaw as TableRow>::row_size(&table_info_ref) as usize];
let mut offset = 0;
module_row
.row_write(&mut buffer, &mut offset, 1, &table_info_ref)
.expect("Serialization should succeed");
let expected = vec![
0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, ];
assert_eq!(
buffer, expected,
"Binary output should match expected format"
);
}
#[test]
fn test_row_size_calculation() {
let table_info_small = TableInfo::new_test(&[], false, false, false);
let table_info_small_ref = Arc::new(table_info_small);
let small_size = <ModuleRaw as TableRow>::row_size(&table_info_small_ref);
assert_eq!(small_size, 2 + 2 + 2 + 2 + 2);
let table_info_large = TableInfo::new_test(&[], true, true, true);
let table_info_large_ref = Arc::new(table_info_large);
let large_size = <ModuleRaw as TableRow>::row_size(&table_info_large_ref);
assert_eq!(large_size, 2 + 4 + 4 + 4 + 4); }
}