deflateoutputstreambuf.cpp
Go to the documentation of this file.00001
00002 #include "zipios-config.h"
00003
00004 #include "meta-iostreams.h"
00005
00006 #include <zlib.h>
00007
00008 #include "fcollexceptions.h"
00009 #include "deflateoutputstreambuf.h"
00010
00011 #include "outputstringstream.h"
00012
00013 namespace zipios {
00014
00015 using std::cerr ;
00016 using std::endl ;
00017
00018 DeflateOutputStreambuf::DeflateOutputStreambuf( streambuf *outbuf, bool user_init,
00019 bool del_outbuf )
00020 : FilterOutputStreambuf( outbuf, del_outbuf ),
00021 _zs_initialized ( false ),
00022 _invecsize ( 1000 ),
00023 _invec ( _invecsize ),
00024 _outvecsize ( 1000 ),
00025 _outvec ( _outvecsize )
00026 {
00027
00028
00029
00030
00031
00032
00033 _zs.zalloc = Z_NULL ;
00034 _zs.zfree = Z_NULL ;
00035 _zs.opaque = Z_NULL ;
00036
00037 if ( user_init && ! init() )
00038 cerr << "DeflateOutputStreambuf::reset() failed!\n" ;
00039
00040 }
00041
00042
00043 DeflateOutputStreambuf::~DeflateOutputStreambuf() {
00044 closeStream() ;
00045 }
00046
00047
00048
00049
00050
00051 bool DeflateOutputStreambuf::init( int comp_level ) {
00052 static const int default_mem_level = 8 ;
00053
00054
00055
00056 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
00057 _zs.avail_in = 0 ;
00058
00059 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
00060 _zs.avail_out = _outvecsize ;
00061
00062 int err ;
00063 if( _zs_initialized ) {
00064 endDeflation() ;
00065 err = deflateReset( &_zs ) ;
00066
00067 } else {
00068 err = deflateInit2( &_zs, comp_level, Z_DEFLATED, -MAX_WBITS,
00069 default_mem_level, Z_DEFAULT_STRATEGY ) ;
00070
00071
00072 _zs_initialized = true ;
00073 }
00074
00075
00076 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
00077
00078 _crc32 = crc32( 0, Z_NULL, 0 ) ;
00079 _overflown_bytes = 0 ;
00080
00081 if ( err == Z_OK )
00082 return true ;
00083 else
00084 return false ;
00085 }
00086
00087
00088 bool DeflateOutputStreambuf::closeStream() {
00089 int err = Z_OK ;
00090 if( _zs_initialized ) {
00091 endDeflation() ;
00092 err = deflateEnd( &_zs ) ;
00093 _zs_initialized = false ;
00094 }
00095
00096 if ( err == Z_OK )
00097 return true ;
00098 else {
00099 cerr << "DeflateOutputStreambuf::closeStream(): deflateEnd failed" ;
00100 #ifdef HAVE_ZERROR
00101 cerr << ": " << zError( err ) ;
00102 #endif
00103 cerr << endl ;
00104 return false ;
00105 }
00106 }
00107
00108
00109 int DeflateOutputStreambuf::overflow( int c ) {
00110 _zs.avail_in = pptr() - pbase() ;
00111 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
00112
00113 _crc32 = crc32( _crc32, _zs.next_in, _zs.avail_in ) ;
00114 _overflown_bytes += _zs.avail_in ;
00115
00116 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
00117 _zs.avail_out = _outvecsize ;
00118
00119
00120 int err = Z_OK ;
00121 while ( ( _zs.avail_in > 0 || _zs.avail_out == 0 ) && err == Z_OK ) {
00122 if ( _zs.avail_out == 0 )
00123 flushOutvec() ;
00124
00125 err = deflate( &_zs, Z_NO_FLUSH ) ;
00126 }
00127
00128 flushOutvec() ;
00129
00130
00131 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
00132
00133 if( err != Z_OK && err != Z_STREAM_END ) {
00134 #if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
00135
00136 OutputStringStream msgs ;
00137 msgs << "Deflation failed" ;
00138 #ifdef HAVE_ZERROR
00139 msgs << ": " << zError( err ) ;
00140 #endif
00141 throw IOException( msgs.str() ) ;
00142 #endif
00143 cerr << "Deflation failed\n" ;
00144 return EOF ;
00145 }
00146
00147 if ( c != EOF ) {
00148 *pptr() = c ;
00149 pbump( 1 ) ;
00150 }
00151
00152 return 0 ;
00153 }
00154
00155 int DeflateOutputStreambuf::sync() {
00156
00157
00158 return 0 ;
00159 }
00160
00161
00162 bool DeflateOutputStreambuf::flushOutvec() {
00163 int deflated_bytes = _outvecsize - _zs.avail_out ;
00164 int bc = _outbuf->sputn( &( _outvec[ 0 ] ), deflated_bytes ) ;
00165
00166 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
00167 _zs.avail_out = _outvecsize ;
00168
00169 return deflated_bytes == bc ;
00170 }
00171
00172
00173 void DeflateOutputStreambuf::endDeflation() {
00174 overflow() ;
00175
00176 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
00177 _zs.avail_out = _outvecsize ;
00178
00179
00180 int err = Z_OK ;
00181
00182 while ( err == Z_OK ) {
00183 if ( _zs.avail_out == 0 )
00184 flushOutvec() ;
00185
00186 err = deflate( &_zs, Z_FINISH ) ;
00187 }
00188
00189 flushOutvec() ;
00190
00191 if ( err != Z_STREAM_END ) {
00192 cerr << "DeflateOutputStreambuf::endDeflation(): deflation failed:\n" ;
00193 #ifdef HAVE_ZERROR
00194 cerr << ": " << zError( err ) ;
00195 #endif
00196 cerr << endl ;
00197 }
00198 }
00199
00200
00201 }
00202
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224