| 124 | } |
| 125 | |
| 126 | Expected<void> zlibDecompressStream( std::istream& in, std::ostream& out, const ZlibParams& params ) |
| 127 | { |
| 128 | Buffer<char> inChunk( cChunkSize ), outChunk( cChunkSize ); |
| 129 | zng_stream stream { |
| 130 | .zalloc = Z_NULL, |
| 131 | .zfree = Z_NULL, |
| 132 | .opaque = Z_NULL, |
| 133 | }; |
| 134 | int ret; |
| 135 | if ( Z_OK != ( ret = zng_inflateInit2( &stream, windowBitsFor( params.rawDeflate ) ) ) ) |
| 136 | return unexpected( zngToString( ret ) ); |
| 137 | |
| 138 | MR_FINALLY { |
| 139 | zng_inflateEnd( &stream ); |
| 140 | }; |
| 141 | |
| 142 | while ( !in.eof() ) |
| 143 | { |
| 144 | in.read( inChunk.data(), inChunk.size() ); |
| 145 | if ( in.bad() ) |
| 146 | return unexpected( "I/O error" ); |
| 147 | stream.next_in = reinterpret_cast<uint8_t*>( inChunk.data() ); |
| 148 | stream.avail_in = (unsigned)in.gcount(); |
| 149 | assert( stream.avail_in <= (unsigned)inChunk.size() ); |
| 150 | |
| 151 | do |
| 152 | { |
| 153 | stream.next_out = reinterpret_cast<uint8_t*>( outChunk.data() ); |
| 154 | stream.avail_out = (unsigned)outChunk.size(); |
| 155 | ret = zng_inflate( &stream, Z_NO_FLUSH ); |
| 156 | if ( Z_OK != ret && Z_STREAM_END != ret ) |
| 157 | return unexpected( zngToString( ret ) ); |
| 158 | |
| 159 | assert( stream.avail_out <= (unsigned)outChunk.size() ); |
| 160 | out.write( outChunk.data(), (unsigned)outChunk.size() - stream.avail_out ); |
| 161 | if ( out.bad() ) |
| 162 | return unexpected( "I/O error" ); |
| 163 | |
| 164 | if ( Z_STREAM_END == ret ) |
| 165 | return {}; |
| 166 | } |
| 167 | while ( stream.avail_out == 0 ); |
| 168 | } |
| 169 | |
| 170 | return {}; |
| 171 | } |
| 172 | |
| 173 | Expected<void> zlibDecompressStream( std::istream& in, std::ostream& out ) |
| 174 | { |