45 # if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
50 #endif // GENESIS_ZLIB
64 struct GzipInputSource::ZlibData
72 bool initialized =
false;
78 char in_buf[ BlockLength ];
88 struct GzipInputSource::ZlibData
93 #endif // GENESIS_ZLIB
102 std::shared_ptr<BaseInputSource> input_source,
105 : input_source_( input_source )
107 , format_name_( translate_format_( format ))
111 []( ZlibData *impl ) {
delete impl; }
122 void GzipInputSource::create_zstream_()
124 assert( zlib_data_ );
125 assert( zlib_data_->initialized ==
false );
126 auto& zstream = zlib_data_->zstream;
129 zstream = z_stream();
130 zstream.zalloc = Z_NULL;
131 zstream.zfree = Z_NULL;
132 zstream.opaque = Z_NULL;
133 zstream.avail_in = 0;
134 zstream.next_in = Z_NULL;
137 auto ret = inflateInit2( &zstream, get_format_( format_ ));
142 zlib_data_->initialized =
true;
145 void GzipInputSource::destroy_zstream_()
152 assert( zlib_data_ );
153 if( zlib_data_->initialized ) {
155 inflateEnd( &zlib_data_->zstream );
156 zlib_data_->initialized =
false;
160 size_t GzipInputSource::read_(
char* buffer,
size_t size )
163 assert( zlib_data_ );
164 auto& zstream = zlib_data_->zstream;
165 auto& in_buf = zlib_data_->in_buf;
166 auto& in_pos = zlib_data_->in_pos;
167 auto& in_end = zlib_data_->in_end;
172 size_t const out_end = size;
173 char* out_buf = buffer;
176 while( out_pos < out_end ) {
180 if( in_pos >= in_end ) {
182 in_end = input_source_->read( in_buf, BlockLength );
184 assert( in_end >= in_pos );
185 assert( out_end >= out_pos );
188 if( in_pos == in_end ) {
194 assert( zlib_data_ );
195 if( ! zlib_data_->initialized ) {
203 zstream.avail_in =
static_cast<unsigned int>( in_end - in_pos );
204 zstream.next_in =
reinterpret_cast<Bytef*
>( in_buf ) + in_pos;
207 zstream.avail_out =
static_cast<unsigned int>( out_end - out_pos );
208 zstream.next_out =
reinterpret_cast<Bytef*
>( out_buf ) + out_pos;
211 auto ret = inflate( &zstream, Z_NO_FLUSH );
214 assert( ret != Z_STREAM_ERROR );
215 if( ret != Z_OK && ret != Z_STREAM_END ) {
216 if( ret == Z_NEED_DICT ) {
219 throw GzipError( zstream.msg, ret );
223 in_pos = in_end - zstream.avail_in;
224 out_pos = out_end - zstream.avail_out;
225 assert(
reinterpret_cast<char*
>( zstream.next_in ) == in_buf + in_pos );
226 assert(
reinterpret_cast<char*
>( zstream.next_out ) == out_buf + out_pos );
233 if( ret == Z_STREAM_END ) {
240 assert( out_pos == out_end || in_pos == in_end );
246 std::string GzipInputSource::source_string_()
const
249 auto const bn =
file_basename( input_source_->source_string() );
253 if( ex ==
"gz" || ex ==
"gzip" || ex ==
"zlib" ) {
256 return input_source_->source_string();
267 return MAX_WBITS | 32;
269 return MAX_WBITS | 16;
301 #else // GENESIS_ZLIB
317 std::shared_ptr<BaseInputSource>,
322 , zlib_data_( nullptr, []( ZlibData* ){} )
325 throw std::runtime_error(
"zlib: Genesis was not compiled with zlib support." );
328 void GzipInputSource::create_zstream_()
333 void GzipInputSource::destroy_zstream_()
338 size_t GzipInputSource::read_(
char*,
size_t )
343 std::string GzipInputSource::source_string_()
const
360 #endif // GENESIS_ZLIB