@@ -2279,3 +2279,128 @@ fn codes_used() {
22792279 } ) ;
22802280 }
22812281}
2282+
2283+ #[ test]
2284+ fn test_dict_inflate ( ) {
2285+ // Maximum dictionary size, according to inflateGetDictionary() description.
2286+ const MAX_DICTIONARY_SIZE : usize = 32768 ;
2287+
2288+ let mut dictionary = * b"hello\0 " ;
2289+ let mut hello = * b"hello\0 " ;
2290+
2291+ let ( compr, dict_id) = assert_eq_rs_ng ! ( {
2292+ let mut compr = [ 0u8 ; 1024 ] ;
2293+
2294+ let mut strm = MaybeUninit :: zeroed( ) ;
2295+
2296+ let ret = unsafe {
2297+ deflateInit_(
2298+ strm. as_mut_ptr( ) ,
2299+ Z_BEST_COMPRESSION ,
2300+ zlibVersion( ) ,
2301+ core:: mem:: size_of:: <z_stream>( ) as _,
2302+ )
2303+ } ;
2304+
2305+ let c_stream = unsafe { strm. assume_init_mut( ) } ;
2306+
2307+ assert_eq!( ReturnCode :: from( ret) , ReturnCode :: Ok ) ;
2308+
2309+ let err =
2310+ unsafe { deflateSetDictionary( c_stream, dictionary. as_ptr( ) , dictionary. len( ) as _) } ;
2311+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2312+
2313+ let dict_id = c_stream. adler;
2314+ c_stream. avail_out = compr. len( ) as _;
2315+ c_stream. next_out = compr. as_mut_ptr( ) ;
2316+
2317+ c_stream. avail_in = hello. len( ) as _;
2318+ c_stream. next_in = hello. as_mut_ptr( ) ;
2319+
2320+ let err = unsafe { deflate( c_stream, Z_FINISH ) } ;
2321+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: StreamEnd ) ;
2322+
2323+ if err != Z_STREAM_END {
2324+ panic!( "deflate should report Z_STREAM_END\n " ) ;
2325+ }
2326+ let err = unsafe { deflateEnd( c_stream) } ;
2327+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2328+
2329+ ( compr, dict_id)
2330+ } ) ;
2331+
2332+ assert_eq_rs_ng ! ( {
2333+ let mut compr = compr;
2334+ let mut uncompr = * b"garbage garbage garbage\0 " ;
2335+
2336+ let mut stream = MaybeUninit :: <z_stream>:: zeroed( ) ;
2337+
2338+ let err = unsafe {
2339+ inflateInit_(
2340+ stream. as_mut_ptr( ) ,
2341+ zlibVersion( ) ,
2342+ core:: mem:: size_of:: <z_stream>( ) as c_int,
2343+ )
2344+ } ;
2345+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2346+
2347+ let d_stream = stream. assume_init_mut( ) ;
2348+
2349+ d_stream. adler = 0 ;
2350+ d_stream. avail_in = compr. len( ) as _;
2351+ d_stream. next_in = compr. as_mut_ptr( ) ;
2352+
2353+ d_stream. avail_out = uncompr. len( ) as _;
2354+ d_stream. next_out = uncompr. as_mut_ptr( ) ;
2355+
2356+ let mut check_dictionary = [ 0i8 ; MAX_DICTIONARY_SIZE ] ;
2357+
2358+ loop {
2359+ let mut err = unsafe { inflate( d_stream, Z_NO_FLUSH ) } ;
2360+
2361+ if err == Z_STREAM_END {
2362+ break ;
2363+ }
2364+
2365+ if err == Z_NEED_DICT {
2366+ if d_stream. adler != dict_id {
2367+ panic!( "unexpected dictionary" ) ;
2368+ }
2369+ err = unsafe {
2370+ inflateSetDictionary( d_stream, dictionary. as_mut_ptr( ) , dictionary. len( ) as _)
2371+ } ;
2372+ }
2373+
2374+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2375+ }
2376+
2377+ let mut check_dictionary_len = 0 ;
2378+ let err = unsafe {
2379+ inflateGetDictionary( d_stream, core:: ptr:: null_mut( ) , & mut check_dictionary_len)
2380+ } ;
2381+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2382+
2383+ if ( check_dictionary_len as usize ) < dictionary. len( ) {
2384+ panic!( "bad dictionary length" ) ;
2385+ }
2386+
2387+ let err = unsafe {
2388+ inflateGetDictionary(
2389+ d_stream,
2390+ check_dictionary. as_mut_ptr( ) . cast( ) ,
2391+ & mut check_dictionary_len,
2392+ )
2393+ } ;
2394+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2395+
2396+ assert_eq!(
2397+ dictionary,
2398+ & check_dictionary. map( |c| c as u8 ) [ ..dictionary. len( ) ]
2399+ ) ;
2400+
2401+ let err = unsafe { inflateEnd( d_stream) } ;
2402+ assert_eq!( ReturnCode :: from( err) , ReturnCode :: Ok ) ;
2403+
2404+ assert_eq!( uncompr[ ..hello. len( ) ] , hello) ;
2405+ } ) ;
2406+ }
0 commit comments