@@ -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