@@ -1698,3 +1698,115 @@ fn op_len_edge_case() {
1698
1698
1699
1699
assert_eq ! ( output_rs, output_ng) ;
1700
1700
}
1701
+
1702
+ // Fills the provided buffer with pseudorandom bytes based on the given seed
1703
+ // Duplicates bytes by `step` in a row
1704
+ fn prng_bytes ( seed : u64 , bytes : & mut Vec < u8 > , step : usize ) {
1705
+ const M : u64 = 2u64 . pow ( 32 ) ;
1706
+ const A : u64 = 1664525 ;
1707
+ const C : u64 = 1013904223 ;
1708
+ let mut state = seed;
1709
+ for chunk in bytes. chunks_mut ( 4 * step) {
1710
+ state = ( A * state + C ) % M ;
1711
+ let rand_bytes = state. to_le_bytes ( ) ;
1712
+ for ( i, byte) in chunk. iter_mut ( ) . enumerate ( ) {
1713
+ * byte = rand_bytes[ i / step] ;
1714
+ }
1715
+ }
1716
+ }
1717
+
1718
+ #[ test]
1719
+ fn test_inflate_flush_block ( ) {
1720
+ let window_bits = -15 ; // Raw
1721
+ const CHUNK : usize = 16384 ;
1722
+
1723
+ // Create a compressed vector of random data that's bigger then the zlib block size
1724
+ let mut data = vec ! [ 0u8 ; 160000 ] ;
1725
+ prng_bytes ( 314159 , & mut data, 4 ) ;
1726
+ let config = DeflateConfig {
1727
+ window_bits,
1728
+ ..DeflateConfig :: default ( )
1729
+ } ;
1730
+ let mut output = vec ! [ 0u8 ; 80000 ] ;
1731
+ // Compress the data
1732
+ let ( compressed_data, return_code) = compress_slice ( & mut output, & data, config) ;
1733
+ assert_eq ! ( ReturnCode :: from( return_code) , ReturnCode :: Ok ) ;
1734
+
1735
+ // Log the stream positions and data_type output from libz
1736
+ let mut zlib_log = Vec :: new ( ) ;
1737
+ {
1738
+ let mut stream = MaybeUninit :: < libz_sys:: z_stream > :: zeroed ( ) ;
1739
+
1740
+ let ret = unsafe {
1741
+ libz_sys:: inflateInit2_ (
1742
+ stream. as_mut_ptr ( ) ,
1743
+ window_bits,
1744
+ libz_sys:: zlibVersion ( ) ,
1745
+ core:: mem:: size_of :: < libz_sys:: z_stream > ( ) as c_int ,
1746
+ )
1747
+ } ;
1748
+ assert_eq ! ( ReturnCode :: from( ret) , ReturnCode :: Ok ) ;
1749
+
1750
+ let mut output = vec ! [ 0u8 ; CHUNK * 2 ] ;
1751
+ let stream = unsafe { stream. assume_init_mut ( ) } ;
1752
+ stream. next_in = compressed_data. as_ptr ( ) as * mut u8 ;
1753
+ stream. avail_in = compressed_data. len ( ) as _ ;
1754
+ loop {
1755
+ stream. next_out = output. as_mut_ptr ( ) ;
1756
+ stream. avail_out = output. len ( ) as _ ;
1757
+
1758
+ let ret = unsafe { libz_sys:: inflate ( stream, InflateFlush :: Block as i32 ) } ;
1759
+
1760
+ let log = format ! (
1761
+ "In:{} Out:{} DT:{}" ,
1762
+ stream. avail_in, stream. avail_out, stream. data_type
1763
+ ) ;
1764
+ zlib_log. push ( log) ;
1765
+
1766
+ assert_eq ! ( ReturnCode :: from( ret) , ReturnCode :: Ok ) ;
1767
+
1768
+ if stream. avail_in == 0 {
1769
+ break ;
1770
+ }
1771
+ }
1772
+ }
1773
+
1774
+ // Log the stream positions and data_type output from libz_rs and compare
1775
+ {
1776
+ let mut stream = MaybeUninit :: < z_stream > :: zeroed ( ) ;
1777
+
1778
+ let ret = unsafe {
1779
+ inflateInit2_ (
1780
+ stream. as_mut_ptr ( ) ,
1781
+ window_bits,
1782
+ zlibVersion ( ) ,
1783
+ core:: mem:: size_of :: < z_stream > ( ) as c_int ,
1784
+ )
1785
+ } ;
1786
+ assert_eq ! ( ReturnCode :: from( ret) , ReturnCode :: Ok ) ;
1787
+
1788
+ let mut output = vec ! [ 0u8 ; CHUNK * 2 ] ;
1789
+ let stream = unsafe { stream. assume_init_mut ( ) } ;
1790
+ stream. next_in = compressed_data. as_ptr ( ) as * mut u8 ;
1791
+ stream. avail_in = compressed_data. len ( ) as _ ;
1792
+ loop {
1793
+ stream. next_out = output. as_mut_ptr ( ) ;
1794
+ stream. avail_out = output. len ( ) as _ ;
1795
+
1796
+ let ret = unsafe { inflate ( stream, InflateFlush :: Block as i32 ) } ;
1797
+
1798
+ let log = format ! (
1799
+ "In:{} Out:{} DT:{}" ,
1800
+ stream. avail_in, stream. avail_out, stream. data_type
1801
+ ) ;
1802
+ // Compare log entries
1803
+ assert_eq ! ( zlib_log. remove( 0 ) , log) ;
1804
+
1805
+ assert_eq ! ( ReturnCode :: from( ret) , ReturnCode :: Ok ) ;
1806
+
1807
+ if stream. avail_in == 0 {
1808
+ break ;
1809
+ }
1810
+ }
1811
+ }
1812
+ }
0 commit comments