11//! Implementation for C backends.
2- use std:: alloc:: { self , Layout } ;
32use std:: cmp;
4- use std:: convert:: TryFrom ;
53use std:: fmt;
64use std:: marker;
7- use std:: os:: raw:: { c_int, c_uint, c_void } ;
5+ use std:: os:: raw:: { c_int, c_uint} ;
86use std:: ptr;
97
108use super :: * ;
@@ -52,14 +50,28 @@ impl Default for StreamWrapper {
5250 reserved : 0 ,
5351 opaque : ptr:: null_mut ( ) ,
5452 state : ptr:: null_mut ( ) ,
55- #[ cfg( all( feature = "any_zlib" , not( feature = "cloudflare-zlib-sys" ) ) ) ]
56- zalloc,
57- #[ cfg( all( feature = "any_zlib" , not( feature = "cloudflare-zlib-sys" ) ) ) ]
58- zfree,
59- #[ cfg( not( all( feature = "any_zlib" , not( feature = "cloudflare-zlib-sys" ) ) ) ) ]
60- zalloc : Some ( zalloc) ,
61- #[ cfg( not( all( feature = "any_zlib" , not( feature = "cloudflare-zlib-sys" ) ) ) ) ]
62- zfree : Some ( zfree) ,
53+ #[ cfg( all(
54+ feature = "any_zlib" ,
55+ not( any( feature = "cloudflare-zlib-sys" , feature = "libz-rs-sys" ) )
56+ ) ) ]
57+ zalloc : allocator:: zalloc,
58+ #[ cfg( all(
59+ feature = "any_zlib" ,
60+ not( any( feature = "cloudflare-zlib-sys" , feature = "libz-rs-sys" ) )
61+ ) ) ]
62+ zfree : allocator:: zfree,
63+
64+ #[ cfg( all( feature = "any_zlib" , feature = "cloudflare-zlib-sys" ) ) ]
65+ zalloc : Some ( allocator:: zalloc) ,
66+ #[ cfg( all( feature = "any_zlib" , feature = "cloudflare-zlib-sys" ) ) ]
67+ zfree : Some ( allocator:: zfree) ,
68+
69+ // for zlib-rs, it is most efficient to have it provide the allocator.
70+ // The libz-rs-sys dependency is configured to use the rust system allocator
71+ #[ cfg( all( feature = "any_zlib" , feature = "libz-rs-sys" ) ) ]
72+ zalloc : None ,
73+ #[ cfg( all( feature = "any_zlib" , feature = "libz-rs-sys" ) ) ]
74+ zfree : None ,
6375 } ) ) ,
6476 }
6577 }
@@ -75,54 +87,63 @@ impl Drop for StreamWrapper {
7587 }
7688}
7789
78- const ALIGN : usize = std:: mem:: align_of :: < usize > ( ) ;
90+ #[ cfg( all( feature = "any_zlib" , not( feature = "libz-rs-sys" ) ) ) ]
91+ mod allocator {
92+ use super :: * ;
7993
80- fn align_up ( size : usize , align : usize ) -> usize {
81- ( size + align - 1 ) & !( align - 1 )
82- }
94+ use std:: alloc:: { self , Layout } ;
95+ use std:: convert:: TryFrom ;
96+ use std:: os:: raw:: c_void;
97+
98+ const ALIGN : usize = std:: mem:: align_of :: < usize > ( ) ;
99+
100+ fn align_up ( size : usize , align : usize ) -> usize {
101+ ( size + align - 1 ) & !( align - 1 )
102+ }
103+
104+ pub extern "C" fn zalloc ( _ptr : * mut c_void , items : uInt , item_size : uInt ) -> * mut c_void {
105+ // We need to multiply `items` and `item_size` to get the actual desired
106+ // allocation size. Since `zfree` doesn't receive a size argument we
107+ // also need to allocate space for a `usize` as a header so we can store
108+ // how large the allocation is to deallocate later.
109+ let size = match items
110+ . checked_mul ( item_size)
111+ . and_then ( |i| usize:: try_from ( i) . ok ( ) )
112+ . map ( |size| align_up ( size, ALIGN ) )
113+ . and_then ( |i| i. checked_add ( std:: mem:: size_of :: < usize > ( ) ) )
114+ {
115+ Some ( i) => i,
116+ None => return ptr:: null_mut ( ) ,
117+ } ;
118+
119+ // Make sure the `size` isn't too big to fail `Layout`'s restrictions
120+ let layout = match Layout :: from_size_align ( size, ALIGN ) {
121+ Ok ( layout) => layout,
122+ Err ( _) => return ptr:: null_mut ( ) ,
123+ } ;
83124
84- extern "C" fn zalloc ( _ptr : * mut c_void , items : AllocSize , item_size : AllocSize ) -> * mut c_void {
85- // We need to multiply `items` and `item_size` to get the actual desired
86- // allocation size. Since `zfree` doesn't receive a size argument we
87- // also need to allocate space for a `usize` as a header so we can store
88- // how large the allocation is to deallocate later.
89- let size = match items
90- . checked_mul ( item_size)
91- . and_then ( |i| usize:: try_from ( i) . ok ( ) )
92- . map ( |size| align_up ( size, ALIGN ) )
93- . and_then ( |i| i. checked_add ( std:: mem:: size_of :: < usize > ( ) ) )
94- {
95- Some ( i) => i,
96- None => return ptr:: null_mut ( ) ,
97- } ;
98-
99- // Make sure the `size` isn't too big to fail `Layout`'s restrictions
100- let layout = match Layout :: from_size_align ( size, ALIGN ) {
101- Ok ( layout) => layout,
102- Err ( _) => return ptr:: null_mut ( ) ,
103- } ;
104-
105- unsafe {
106- // Allocate the data, and if successful store the size we allocated
107- // at the beginning and then return an offset pointer.
108- let ptr = alloc:: alloc ( layout) as * mut usize ;
109- if ptr. is_null ( ) {
110- return ptr as * mut c_void ;
125+ unsafe {
126+ // Allocate the data, and if successful store the size we allocated
127+ // at the beginning and then return an offset pointer.
128+ let ptr = alloc:: alloc ( layout) as * mut usize ;
129+ if ptr. is_null ( ) {
130+ return ptr as * mut c_void ;
131+ }
132+ * ptr = size;
133+ ptr. add ( 1 ) as * mut c_void
111134 }
112- * ptr = size;
113- ptr. add ( 1 ) as * mut c_void
114135 }
115- }
116136
117- extern "C" fn zfree ( _ptr : * mut c_void , address : * mut c_void ) {
118- unsafe {
119- // Move our address being freed back one pointer, read the size we
120- // stored in `zalloc`, and then free it using the standard Rust
121- // allocator.
122- let ptr = ( address as * mut usize ) . offset ( -1 ) ;
123- let size = * ptr;
124- let layout = Layout :: from_size_align_unchecked ( size, ALIGN ) ;
125- alloc:: dealloc ( ptr as * mut u8 , layout)
137+ pub extern "C" fn zfree ( _ptr : * mut c_void , address : * mut c_void ) {
138+ unsafe {
139+ // Move our address being freed back one pointer, read the size we
140+ // stored in `zalloc`, and then free it using the standard Rust
141+ // allocator.
142+ let ptr = ( address as * mut usize ) . offset ( -1 ) ;
143+ let size = * ptr;
144+ let layout = Layout :: from_size_align_unchecked ( size, ALIGN ) ;
145+ alloc:: dealloc ( ptr as * mut u8 , layout)
146+ }
126147 }
127148}
128149
@@ -382,10 +403,17 @@ mod c_backend {
382403 #[ cfg( feature = "zlib-ng" ) ]
383404 use libz_ng_sys as libz;
384405
406+ #[ cfg( feature = "zlib-rs" ) ]
407+ use libz_rs_sys as libz;
408+
385409 #[ cfg( all( not( feature = "zlib-ng" ) , feature = "cloudflare_zlib" ) ) ]
386410 use cloudflare_zlib_sys as libz;
387411
388- #[ cfg( all( not( feature = "cloudflare_zlib" ) , not( feature = "zlib-ng" ) ) ) ]
412+ #[ cfg( all(
413+ not( feature = "cloudflare_zlib" ) ,
414+ not( feature = "zlib-ng" ) ,
415+ not( feature = "zlib-rs" )
416+ ) ) ]
389417 use libz_sys as libz;
390418
391419 pub use libz:: deflate as mz_deflate;
@@ -410,13 +438,14 @@ mod c_backend {
410438 pub use libz:: Z_STREAM_END as MZ_STREAM_END ;
411439 pub use libz:: Z_STREAM_ERROR as MZ_STREAM_ERROR ;
412440 pub use libz:: Z_SYNC_FLUSH as MZ_SYNC_FLUSH ;
413- pub type AllocSize = libz:: uInt ;
414441
415442 pub const MZ_DEFAULT_WINDOW_BITS : c_int = 15 ;
416443
417444 #[ cfg( feature = "zlib-ng" ) ]
418445 const ZLIB_VERSION : & ' static str = "2.1.0.devel\0 " ;
419- #[ cfg( not( feature = "zlib-ng" ) ) ]
446+ #[ cfg( feature = "zlib-rs" ) ]
447+ const ZLIB_VERSION : & ' static str = "0.1.0\0 " ;
448+ #[ cfg( not( any( feature = "zlib-ng" , feature = "zlib-rs" ) ) ) ]
420449 const ZLIB_VERSION : & ' static str = "1.2.8\0 " ;
421450
422451 pub unsafe extern "C" fn mz_deflateInit2 (
0 commit comments