@@ -21,6 +21,10 @@ use crate::assert_eq_rs_ng;
2121const VERSION : * const c_char = libz_rs_sys:: zlibVersion ( ) ;
2222const STREAM_SIZE : c_int = core:: mem:: size_of :: < libz_rs_sys:: z_stream > ( ) as c_int ;
2323
24+ const PAPER_100K : & [ u8 ] = include_bytes ! ( "test-data/paper-100k.pdf" ) ;
25+ const FIREWORKS : & [ u8 ] = include_bytes ! ( "test-data/fireworks.jpg" ) ;
26+ const LCET10 : & str = include_str ! ( "test-data/lcet10.txt" ) ;
27+
2428pub mod quick {
2529 use super :: * ;
2630
@@ -1358,17 +1362,31 @@ fn test_deflate_hash_head_0() {
13581362}
13591363
13601364#[ test]
1361- fn test_deflate_copy ( ) {
1362- const HELLO : & str = "hello, hello!\0 " ;
1365+ fn test_deflate_copy_small ( ) {
1366+ test_deflate_copy_help ( "hello, hello!\0 " . as_bytes ( ) )
1367+ }
1368+
1369+ #[ test]
1370+ #[ cfg_attr( miri, ignore = "too slow" ) ]
1371+ fn test_deflate_copy_large ( ) {
1372+ test_deflate_copy_help ( LCET10 . as_bytes ( ) )
1373+ }
13631374
1375+ /// This test
1376+ ///
1377+ /// - compresses half of the input, flushes, then compresses the remainder
1378+ /// - compresses half of the input, flushes, copies the state, then compresses
1379+ /// the remainder using the copy
1380+ ///
1381+ /// It then asserts that the output is the same, testing that the copy was succesful.
1382+ fn test_deflate_copy_help ( input : & [ u8 ] ) {
13641383 let config = DeflateConfig :: default ( ) ;
13651384
1366- let mut strm = MaybeUninit :: zeroed ( ) ;
1385+ let _ = assert_eq_rs_ng ! ( {
1386+ let mut strm_full = MaybeUninit :: zeroed( ) ;
13671387
1368- unsafe {
1369- // first validate the config
1370- let err = libz_rs_sys:: deflateInit2_ (
1371- strm. as_mut_ptr ( ) ,
1388+ let err = deflateInit2_(
1389+ strm_full. as_mut_ptr( ) ,
13721390 config. level,
13731391 config. method as i32 ,
13741392 config. window_bits,
@@ -1379,46 +1397,163 @@ fn test_deflate_copy() {
13791397 ) ;
13801398 assert_eq!( err, 0 ) ;
13811399
1382- let strm = strm . assume_init_mut ( ) ;
1400+ let strm_full = strm_full . assume_init_mut( ) ;
13831401
1384- let mut compr = [ 0 ; 32 ] ;
1385- strm. next_in = HELLO . as_ptr ( ) as * mut u8 ;
1386- strm. next_out = compr. as_mut_ptr ( ) ;
1402+ let mut full_out = vec![ 0u8 ; input. len( ) * 2 + 64 ] ;
13871403
1388- for _ in HELLO . as_bytes ( ) {
1389- strm. avail_in = 1 ;
1390- strm. avail_out = 1 ;
1404+ strm_full. next_out = full_out. as_mut_ptr( ) ;
1405+ strm_full. avail_out = full_out. len( ) as u32 ;
1406+
1407+ let half_full = input. len( ) / 2 ;
1408+ let mut pos_full = 0 ;
1409+
1410+ while pos_full < half_full {
1411+ strm_full. next_in = input. as_ptr( ) . add( pos_full) as * mut u8 ;
1412+ let before_in = strm_full. total_in;
1413+ strm_full. avail_in = ( half_full - pos_full) as u32 ;
13911414
1392- let err = libz_rs_sys :: deflate ( strm , DeflateFlush :: NoFlush as i32 ) ;
1415+ let err = deflate( strm_full , DeflateFlush :: NoFlush as i32 ) ;
13931416 assert_eq!( err, 0 ) ;
1417+ assert_ne!( strm_full. avail_out, 0 ) ;
1418+
1419+ let used = ( strm_full. total_in - before_in) as usize ;
1420+ assert!( used > 0 ) ;
1421+ pos_full += used;
13941422 }
13951423
1396- loop {
1397- strm. avail_out = 1 ;
1398- let err = libz_rs_sys:: deflate ( strm, DeflateFlush :: Finish as i32 ) ;
1424+ strm_full. next_in = core:: ptr:: null_mut( ) ;
1425+ strm_full. avail_in = 0 ;
1426+ let err = deflate( strm_full, DeflateFlush :: SyncFlush as i32 ) ;
1427+ assert_eq!( err, 0 ) ;
1428+ assert_ne!( strm_full. avail_out, 0 ) ;
1429+
1430+ while pos_full < input. len( ) {
1431+ strm_full. next_in = input. as_ptr( ) . add( pos_full) as * mut u8 ;
1432+ let before_in = strm_full. total_in;
1433+ strm_full. avail_in = ( input. len( ) - pos_full) as u32 ;
13991434
1435+ let err = deflate( strm_full, DeflateFlush :: NoFlush as i32 ) ;
1436+ assert_eq!( err, 0 ) ;
1437+ assert_ne!( strm_full. avail_out, 0 ) ;
1438+
1439+ let used = ( strm_full. total_in - before_in) as usize ;
1440+ assert!( used > 0 ) ;
1441+ pos_full += used;
1442+ }
1443+
1444+ strm_full. next_in = core:: ptr:: null_mut( ) ;
1445+ strm_full. avail_in = 0 ;
1446+ let err = deflate( strm_full, DeflateFlush :: SyncFlush as i32 ) ;
1447+ assert_eq!( err, 0 ) ;
1448+ assert_ne!( strm_full. avail_out, 0 ) ;
1449+
1450+ loop {
1451+ let err = deflate( strm_full, DeflateFlush :: Finish as i32 ) ;
14001452 if ReturnCode :: from( err) == ReturnCode :: StreamEnd {
14011453 break ;
14021454 }
1455+ assert_eq!( err, 0 ) ;
1456+ assert_ne!( strm_full. avail_out, 0 ) ;
1457+ }
1458+
1459+ let full_total_out = strm_full. total_out as usize ;
1460+ let err = deflateEnd( strm_full) ;
1461+ assert_eq!( err, 0 ) ;
1462+
1463+ full_out. truncate( full_total_out) ;
1464+
1465+ let mut strm_half = MaybeUninit :: zeroed( ) ;
1466+
1467+ let err = deflateInit2_(
1468+ strm_half. as_mut_ptr( ) ,
1469+ config. level,
1470+ config. method as i32 ,
1471+ config. window_bits,
1472+ config. mem_level,
1473+ config. strategy as i32 ,
1474+ VERSION ,
1475+ STREAM_SIZE ,
1476+ ) ;
1477+ assert_eq!( err, 0 ) ;
14031478
1479+ let strm_half = strm_half. assume_init_mut( ) ;
1480+
1481+ let mut copy_out = vec![ 0u8 ; input. len( ) * 2 + 64 ] ;
1482+
1483+ strm_half. next_out = copy_out. as_mut_ptr( ) ;
1484+ strm_half. avail_out = copy_out. len( ) as u32 ;
1485+
1486+ let half = input. len( ) / 2 ;
1487+ let mut pos = 0 ;
1488+
1489+ while pos < half {
1490+ strm_half. next_in = input. as_ptr( ) . add( pos) as * mut u8 ;
1491+ let before_in = strm_half. total_in;
1492+ strm_half. avail_in = ( half - pos) as u32 ;
1493+
1494+ let err = deflate( strm_half, DeflateFlush :: NoFlush as i32 ) ;
14041495 assert_eq!( err, 0 ) ;
1496+ assert_ne!( strm_half. avail_out, 0 ) ;
1497+
1498+ let used = ( strm_half. total_in - before_in) as usize ;
1499+ assert!( used > 0 ) ;
1500+ pos += used;
14051501 }
14061502
1503+ strm_half. next_in = core:: ptr:: null_mut( ) ;
1504+ strm_half. avail_in = 0 ;
1505+ let err = deflate( strm_half, DeflateFlush :: SyncFlush as i32 ) ;
1506+ assert_eq!( err, 0 ) ;
1507+ assert_ne!( strm_half. avail_out, 0 ) ;
1508+
14071509 let mut copy = MaybeUninit :: uninit( ) ;
1408- let err = libz_rs_sys :: deflateCopy ( copy. as_mut_ptr ( ) , strm ) ;
1510+ let err = deflateCopy( copy. as_mut_ptr( ) , strm_half ) ;
14091511 assert_eq!( err, 0 ) ;
14101512
1411- assert_eq ! (
1412- * ( strm. state as * const u8 ) ,
1413- * ( ( ( * copy. as_mut_ptr( ) ) . state) as * const u8 ) ,
1414- ) ;
1513+ let err = deflateEnd( strm_half) ;
1514+ assert_eq!( err, -3 ) ; // still partway through according to your original expectation
14151515
1416- let err = libz_rs_sys:: deflateEnd ( strm) ;
1516+ let copy = copy. assume_init_mut( ) ;
1517+
1518+ while pos < input. len( ) {
1519+ copy. next_in = input. as_ptr( ) . add( pos) as * mut u8 ;
1520+ let before_in = copy. total_in;
1521+ copy. avail_in = ( input. len( ) - pos) as u32 ;
1522+
1523+ let err = deflate( copy, DeflateFlush :: NoFlush as i32 ) ;
1524+ assert_eq!( err, 0 ) ;
1525+ assert_ne!( copy. avail_out, 0 ) ;
1526+
1527+ let used = ( copy. total_in - before_in) as usize ;
1528+ assert!( used > 0 ) ;
1529+ pos += used;
1530+ }
1531+
1532+ copy. next_in = core:: ptr:: null_mut( ) ;
1533+ copy. avail_in = 0 ;
1534+ let err = deflate( copy, DeflateFlush :: SyncFlush as i32 ) ;
14171535 assert_eq!( err, 0 ) ;
1536+ assert_ne!( copy. avail_out, 0 ) ;
14181537
1419- let err = libz_rs_sys:: deflateEnd ( copy. as_mut_ptr ( ) ) ;
1538+ loop {
1539+ let err = deflate( copy, DeflateFlush :: Finish as i32 ) ;
1540+ if ReturnCode :: from( err) == ReturnCode :: StreamEnd {
1541+ break ;
1542+ }
1543+ assert_eq!( err, 0 ) ;
1544+ assert_ne!( copy. avail_out, 0 ) ;
1545+ }
1546+
1547+ let copy_total_out = copy. total_out as usize ;
1548+ let err = deflateEnd( copy) ;
14201549 assert_eq!( err, 0 ) ;
1421- }
1550+
1551+ copy_out. truncate( copy_total_out) ;
1552+
1553+ assert_eq!( full_out, copy_out) ;
1554+
1555+ full_out
1556+ } ) ;
14221557}
14231558
14241559#[ test]
@@ -1642,6 +1777,7 @@ fn gzip_with_header() {
16421777}
16431778
16441779mod fuzz_based_tests {
1780+ use super :: { FIREWORKS , LCET10 , PAPER_100K } ;
16451781 use crate :: helpers:: compress_slice_ng;
16461782 use libz_rs_sys:: gz_header;
16471783 use zlib_rs:: {
@@ -1676,10 +1812,6 @@ mod fuzz_based_tests {
16761812 }
16771813 }
16781814
1679- const PAPER_100K : & [ u8 ] = include_bytes ! ( "test-data/paper-100k.pdf" ) ;
1680- const FIREWORKS : & [ u8 ] = include_bytes ! ( "test-data/fireworks.jpg" ) ;
1681- const LCET10 : & str = include_str ! ( "test-data/lcet10.txt" ) ;
1682-
16831815 #[ test]
16841816 #[ cfg_attr( miri, ignore = "too slow" ) ]
16851817 fn compress_lcet10 ( ) {
0 commit comments