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