Skip to content

Commit 847d9c5

Browse files
committed
feat: add set_flags function with serialization support
1 parent 4df6302 commit 847d9c5

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

tbf-parser/src/types.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,4 +1183,77 @@ impl TbfHeader {
11831183
_ => None,
11841184
}
11851185
}
1186+
1187+
pub fn compute_checksum(header: &[u8], new_flags: u32) -> Result<u32, TbfParseError> {
1188+
let mut checksum: u32 = 0;
1189+
1190+
let header_iter = header.chunks_exact(4);
1191+
1192+
// Iterate all chunks and XOR the chunks to compute the checksum.
1193+
for (i, chunk) in header_iter.enumerate() {
1194+
let word = if i == 2 {
1195+
new_flags
1196+
} else if i == 3 {
1197+
continue;
1198+
} else {
1199+
u32::from_le_bytes(chunk.try_into()?)
1200+
};
1201+
checksum ^= word;
1202+
}
1203+
Ok(checksum)
1204+
}
1205+
1206+
pub fn set_flags(&mut self, flags: u32, header: &[u8]) -> Result<[u8; 16], TbfParseError> {
1207+
let new_checksum = Self::compute_checksum(header, flags)?;
1208+
match self {
1209+
TbfHeader::TbfHeaderV2(hd) => {
1210+
hd.base.flags = flags;
1211+
hd.base.checksum = new_checksum;
1212+
}
1213+
TbfHeader::Padding(base) => {
1214+
base.flags = flags;
1215+
base.checksum = new_checksum;
1216+
}
1217+
}
1218+
1219+
self.serialize()
1220+
}
1221+
1222+
pub fn serialize(&self) -> Result<[u8; 16], TbfParseError> {
1223+
match self {
1224+
TbfHeader::TbfHeaderV2(hd) => {
1225+
let base = &hd.base;
1226+
let mut bytes = [0u8; 16];
1227+
bytes[0..2].copy_from_slice(&base.version.to_le_bytes());
1228+
bytes[2..4].copy_from_slice(&base.header_size.to_le_bytes());
1229+
bytes[4..8].copy_from_slice(&base.total_size.to_le_bytes());
1230+
bytes[8..12].copy_from_slice(&base.flags.to_le_bytes());
1231+
bytes[12..16].copy_from_slice(&base.checksum.to_le_bytes());
1232+
Ok(bytes)
1233+
}
1234+
TbfHeader::Padding(base) => {
1235+
let mut bytes = [0u8; 16];
1236+
bytes[0..2].copy_from_slice(&base.version.to_le_bytes());
1237+
bytes[2..4].copy_from_slice(&base.header_size.to_le_bytes());
1238+
bytes[4..8].copy_from_slice(&base.total_size.to_le_bytes());
1239+
bytes[8..12].copy_from_slice(&base.flags.to_le_bytes());
1240+
bytes[12..16].copy_from_slice(&base.checksum.to_le_bytes());
1241+
Ok(bytes)
1242+
}
1243+
}
1244+
}
1245+
1246+
pub fn update_from_serialize(&mut self, bytes: &[u8]) -> Result<(), TbfParseError> {
1247+
let new_base = TbfHeaderV2Base::try_from(&bytes[..])?;
1248+
match self {
1249+
TbfHeader::TbfHeaderV2(hd) => {
1250+
hd.base = new_base;
1251+
Ok(())
1252+
}
1253+
TbfHeader::Padding(base) => {
1254+
*base = new_base;
1255+
Ok(())
1256+
}
1257+
}
1258+
}
11861259
}

0 commit comments

Comments
 (0)