inflateinputstreambuf.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 "inflateinputstreambuf.h"
00010
00011 #include "outputstringstream.h"
00012
00013 namespace zipios {
00014
00015 using std::cerr ;
00016 using std::endl ;
00017
00018 InflateInputStreambuf::InflateInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf )
00019 : FilterInputStreambuf( inbuf, del_inbuf ),
00020 _zs_initialized ( false ),
00021 _invecsize ( 1000 ),
00022 _invec ( _invecsize ),
00023 _outvecsize ( 1000 ),
00024 _outvec ( _outvecsize )
00025 {
00026
00027
00028
00029
00030
00031
00032
00033 _zs.zalloc = Z_NULL ;
00034 _zs.zfree = Z_NULL ;
00035 _zs.opaque = Z_NULL ;
00036
00037 reset( s_pos ) ;
00038
00039
00040
00041 }
00042
00043 InflateInputStreambuf::~InflateInputStreambuf() {
00044
00045 int err = inflateEnd( &_zs ) ;
00046 if( err != Z_OK ) {
00047 cerr << "~inflatebuf: inflateEnd failed" ;
00048 #ifdef HAVE_ZERROR
00049 cerr << ": " << zError( err ) ;
00050 #endif
00051 cerr << endl ;
00052 }
00053 }
00054
00055
00056 int InflateInputStreambuf::underflow() {
00057
00058 if ( gptr() < egptr() )
00059 return static_cast< unsigned char >( *gptr() ) ;
00060
00061
00062 _zs.avail_out = _outvecsize ;
00063 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
00064
00065
00066
00067 int err = Z_OK ;
00068 while ( _zs.avail_out > 0 && err == Z_OK ) {
00069 if ( _zs.avail_in == 0 ) {
00070 int bc = _inbuf->sgetn( &(_invec[ 0 ] ) ,
00071 _invecsize ) ;
00072
00073 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
00074 _zs.avail_in = bc ;
00075
00076
00077
00078
00079 }
00080
00081 err = inflate( &_zs, Z_NO_FLUSH ) ;
00082 }
00083
00084
00085
00086
00087 int inflated_bytes = _outvecsize - _zs.avail_out ;
00088 setg( &( _outvec[ 0 ] ),
00089 &( _outvec[ 0 ] ),
00090 &( _outvec[ 0 ] ) + inflated_bytes ) ;
00091
00092
00093
00094 if( err != Z_OK && err != Z_STREAM_END ) {
00095 #if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
00096
00097 OutputStringStream msgs ;
00098 msgs << "InflateInputStreambuf: inflate failed" ;
00099 #ifdef HAVE_ZERROR
00100 msgs << ": " << zError( err ) ;
00101 #endif
00102 throw IOException( msgs.str() ) ;
00103 #endif
00104
00105
00106 }
00107 if (inflated_bytes > 0 )
00108 return static_cast< unsigned char >( *gptr() ) ;
00109 else
00110 return EOF ;
00111 }
00112
00113
00114
00115
00116
00117 bool InflateInputStreambuf::reset( int stream_position ) {
00118 if ( stream_position >= 0 ) {
00119 _inbuf->pubseekpos( stream_position ) ;
00120 }
00121
00122
00123
00124 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
00125 _zs.avail_in = 0 ;
00126
00127 int err ;
00128 if( _zs_initialized ) {
00129 err = inflateReset( &_zs ) ;
00130 } else {
00131 err = inflateInit2( &_zs, -MAX_WBITS ) ;
00132
00133
00134
00135
00136
00137
00138 _zs_initialized = true ;
00139 }
00140
00141
00142
00143
00144
00145
00146 setg( &( _outvec[ 0 ] ),
00147 &( _outvec[ 0 ] ) + _outvecsize,
00148 &( _outvec[ 0 ] ) + _outvecsize ) ;
00149
00150 if ( err == Z_OK )
00151 return true ;
00152 else
00153 return false ;
00154 }
00155
00156 }
00157
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179