@@ -1174,6 +1174,52 @@ mod tests {
11741174 decode_byte_vec_multi_byte_length_prefix, [ 0xff ; 256 ] , two_fifty_six_bytes_encoded( ) ;
11751175 }
11761176
1177+ #[ test]
1178+ #[ cfg( feature = "alloc" ) ]
1179+ fn byte_vec_decoder_reserves_in_batches ( ) {
1180+ // A small number of extra bytes so we extend exactly by the remainder
1181+ // instead of another full batch.
1182+ let tail_length: usize = 11 ;
1183+
1184+ let total_len = MAX_VECTOR_ALLOCATE + tail_length;
1185+ let total_len_le = u32:: try_from ( total_len) . expect ( "total_len fits u32" ) . to_le_bytes ( ) ;
1186+ let mut decoder = ByteVecDecoder :: new ( ) ;
1187+
1188+ let mut prefix = vec ! [ 0xFE ] ; // total_len_le is a compact size of four bytes.
1189+ prefix. extend_from_slice ( & total_len_le) ;
1190+ prefix. push ( 0xAA ) ;
1191+ let mut prefix_slice = prefix. as_slice ( ) ;
1192+ decoder. push_bytes ( & mut prefix_slice) . expect ( "length plus first element" ) ;
1193+ assert ! ( prefix_slice. is_empty( ) ) ;
1194+
1195+ assert_eq ! ( decoder. buffer. capacity( ) , MAX_VECTOR_ALLOCATE ) ;
1196+ assert_eq ! ( decoder. buffer. len( ) , 1 ) ;
1197+ assert_eq ! ( decoder. buffer[ 0 ] , 0xAA ) ;
1198+
1199+ let fill = vec ! [ 0xBB ; MAX_VECTOR_ALLOCATE - 1 ] ;
1200+ let mut fill_slice = fill. as_slice ( ) ;
1201+ decoder. push_bytes ( & mut fill_slice) . expect ( "fills to batch boundary, full capacity" ) ;
1202+ assert ! ( fill_slice. is_empty( ) ) ;
1203+
1204+ assert_eq ! ( decoder. buffer. capacity( ) , MAX_VECTOR_ALLOCATE ) ;
1205+ assert_eq ! ( decoder. buffer. len( ) , MAX_VECTOR_ALLOCATE ) ;
1206+ assert_eq ! ( decoder. buffer[ MAX_VECTOR_ALLOCATE - 1 ] , 0xBB ) ;
1207+
1208+ let mut tail = vec ! [ 0xCC ] ;
1209+ tail. extend ( [ 0xDD ] . repeat ( tail_length - 1 ) ) ;
1210+ let mut tail_slice = tail. as_slice ( ) ;
1211+ decoder. push_bytes ( & mut tail_slice) . expect ( "fills the remaining bytes" ) ;
1212+ assert ! ( tail_slice. is_empty( ) ) ;
1213+
1214+ assert_eq ! ( decoder. buffer. capacity( ) , MAX_VECTOR_ALLOCATE + tail_length) ;
1215+ assert_eq ! ( decoder. buffer. len( ) , total_len) ;
1216+ assert_eq ! ( decoder. buffer[ MAX_VECTOR_ALLOCATE ] , 0xCC ) ;
1217+
1218+ let result = decoder. end ( ) . unwrap ( ) ;
1219+ assert_eq ! ( result. len( ) , total_len) ;
1220+ assert_eq ! ( result[ total_len - 1 ] , 0xDD ) ;
1221+ }
1222+
11771223 #[ cfg( feature = "alloc" ) ]
11781224 #[ derive( Clone , Debug , PartialEq , Eq ) ]
11791225 pub struct Inner ( u32 ) ;
@@ -1283,6 +1329,55 @@ mod tests {
12831329 assert_eq ! ( got, want) ;
12841330 }
12851331
1332+ #[ test]
1333+ #[ cfg( feature = "alloc" ) ]
1334+ fn vec_decoder_reserves_in_batches ( ) {
1335+ // A small number of extra elements so we extend exactly by the remainder
1336+ // instead of another full batch.
1337+ let tail_length: usize = 11 ;
1338+
1339+ let element_size = core:: mem:: size_of :: < Inner > ( ) ;
1340+ let batch_length = MAX_VECTOR_ALLOCATE / element_size;
1341+ assert ! ( batch_length > 1 ) ;
1342+ let total_len = batch_length + tail_length;
1343+ let total_len_le = u32:: try_from ( total_len) . expect ( "total_len fits u32" ) . to_le_bytes ( ) ;
1344+ let mut decoder = Test :: decoder ( ) ;
1345+
1346+ let mut prefix = vec ! [ 0xFE ] ; // total_len_le is a compact size of four bytes.
1347+ prefix. extend_from_slice ( & total_len_le) ;
1348+ prefix. extend_from_slice ( & 0xAA_u32 . to_le_bytes ( ) ) ;
1349+ let mut prefix_slice = prefix. as_slice ( ) ;
1350+ decoder. push_bytes ( & mut prefix_slice) . expect ( "length plus first element" ) ;
1351+ assert ! ( prefix_slice. is_empty( ) ) ;
1352+
1353+ assert_eq ! ( decoder. 0 . buffer. capacity( ) , batch_length) ;
1354+ assert_eq ! ( decoder. 0 . buffer. len( ) , 1 ) ;
1355+ assert_eq ! ( decoder. 0 . buffer[ 0 ] , Inner ( 0xAA ) ) ;
1356+
1357+ let fill = 0xBB_u32 . to_le_bytes ( ) . repeat ( batch_length - 1 ) ;
1358+ let mut fill_slice = fill. as_slice ( ) ;
1359+ decoder. push_bytes ( & mut fill_slice) . expect ( "fills to batch boundary, full capacity" ) ;
1360+ assert ! ( fill_slice. is_empty( ) ) ;
1361+
1362+ assert_eq ! ( decoder. 0 . buffer. capacity( ) , batch_length) ;
1363+ assert_eq ! ( decoder. 0 . buffer. len( ) , batch_length) ;
1364+ assert_eq ! ( decoder. 0 . buffer[ batch_length - 1 ] , Inner ( 0xBB ) ) ;
1365+
1366+ let mut tail = 0xCC_u32 . to_le_bytes ( ) . to_vec ( ) ;
1367+ tail. extend ( 0xDD_u32 . to_le_bytes ( ) . repeat ( tail_length - 1 ) ) ;
1368+ let mut tail_slice = tail. as_slice ( ) ;
1369+ decoder. push_bytes ( & mut tail_slice) . expect ( "fills the remaining bytes" ) ;
1370+ assert ! ( tail_slice. is_empty( ) ) ;
1371+
1372+ assert_eq ! ( decoder. 0 . buffer. capacity( ) , batch_length + tail_length) ;
1373+ assert_eq ! ( decoder. 0 . buffer. len( ) , total_len) ;
1374+ assert_eq ! ( decoder. 0 . buffer[ batch_length] , Inner ( 0xCC ) ) ;
1375+
1376+ let Test ( result) = decoder. end ( ) . unwrap ( ) ;
1377+ assert_eq ! ( result. len( ) , total_len) ;
1378+ assert_eq ! ( result[ total_len - 1 ] , Inner ( 0xDD ) ) ;
1379+ }
1380+
12861381 #[ cfg( feature = "alloc" ) ]
12871382 fn two_fifty_six_elements ( ) -> Test {
12881383 Test ( iter:: repeat ( Inner ( 0xDEAD_BEEF ) ) . take ( 256 ) . collect ( ) )
0 commit comments