2 #include "zipios++/zipios-config.h"
4 #include "zipios++/meta-iostreams.h"
8 #include "zipios++/fcollexceptions.h"
9 #include "zipios++/deflateoutputstreambuf.h"
11 #include "outputstringstream.h"
18 DeflateOutputStreambuf::DeflateOutputStreambuf( streambuf *outbuf, bool user_init,
20 : FilterOutputStreambuf( outbuf, del_outbuf ),
21 _zs_initialized ( false ),
23 _invec ( _invecsize ),
25 _outvec ( _outvecsize )
27 // NOTICE: It is important that this constructor and the methods it
28 // calls doesn't do anything with the output streambuf _outbuf The
29 // reason is that this class can be subclassed, and the subclass
30 // should get a chance to write to the buffer first
37 if ( user_init && ! init() )
38 cerr << "DeflateOutputStreambuf::reset() failed!\n" ; // FIXME: throw something
43 DeflateOutputStreambuf::~DeflateOutputStreambuf() {
48 // This method is called in the constructor, so it must not write
49 // anything to the output streambuf _outbuf (see notice in
51 bool DeflateOutputStreambuf::init( int comp_level ) {
52 static const int default_mem_level = 8 ;
54 // _zs.next_in and avail_in must be set according to
55 // zlib.h (inline doc).
56 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
59 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
60 _zs.avail_out = _outvecsize ;
63 if( _zs_initialized ) { // just reset it
65 err = deflateReset( &_zs ) ;
66 // FIXME: bug, for deflateReset we do not update the compression level
68 err = deflateInit2( &_zs, comp_level, Z_DEFLATED, -MAX_WBITS,
69 default_mem_level, Z_DEFAULT_STRATEGY ) ;
70 /* windowBits is passed < 0 to tell that no zlib header should be
72 _zs_initialized = true ;
76 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
78 _crc32 = crc32( 0, Z_NULL, 0 ) ;
79 _overflown_bytes = 0 ;
88 bool DeflateOutputStreambuf::closeStream() {
90 if( _zs_initialized ) {
92 err = deflateEnd( &_zs ) ;
93 _zs_initialized = false ;
99 cerr << "DeflateOutputStreambuf::closeStream(): deflateEnd failed" ;
101 cerr << ": " << zError( err ) ;
109 int DeflateOutputStreambuf::overflow( int c ) {
110 _zs.avail_in = static_cast< uInt >( pptr() - pbase() ) ;
111 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
113 _crc32 = crc32( _crc32, _zs.next_in, _zs.avail_in ) ; // update crc32
114 _overflown_bytes += _zs.avail_in ;
116 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
117 _zs.avail_out = _outvecsize ;
119 // Deflate until _invec is empty.
121 while ( ( _zs.avail_in > 0 || _zs.avail_out == 0 ) && err == Z_OK ) {
122 if ( _zs.avail_out == 0 )
125 err = deflate( &_zs, Z_NO_FLUSH ) ;
130 // Update 'put' pointers
131 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
133 if( err != Z_OK && err != Z_STREAM_END ) {
134 #if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
135 // Throw an exception to make istream set badbit
136 OutputStringStream msgs ;
137 msgs << "Deflation failed" ;
139 msgs << ": " << zError( err ) ;
141 throw IOException( msgs.str() ) ;
143 cerr << "Deflation failed\n" ;
155 int DeflateOutputStreambuf::sync() {
156 // FIXME: Do something
157 // return overflow() ;
162 bool DeflateOutputStreambuf::flushOutvec() {
163 int deflated_bytes = _outvecsize - _zs.avail_out ;
164 int bc = static_cast< int >( _outbuf->sputn( &( _outvec[ 0 ] ), deflated_bytes ) ) ;
166 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
167 _zs.avail_out = _outvecsize ;
169 return deflated_bytes == bc ;
173 void DeflateOutputStreambuf::endDeflation() {
176 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
177 _zs.avail_out = _outvecsize ;
179 // Deflate until _invec is empty.
182 while ( err == Z_OK ) {
183 if ( _zs.avail_out == 0 )
186 err = deflate( &_zs, Z_FINISH ) ;
191 if ( err != Z_STREAM_END ) {
192 cerr << "DeflateOutputStreambuf::endDeflation(): deflation failed:\n" ;
194 cerr << ": " << zError( err ) ;
204 Implementation of DeflateOutputStreambuf.
208 Zipios++ - a small C++ library that provides easy access to .zip files.
209 Copyright (C) 2000 Thomas Søndergaard
211 This library is free software; you can redistribute it and/or
212 modify it under the terms of the GNU Lesser General Public
213 License as published by the Free Software Foundation; either
214 version 2 of the License, or (at your option) any later version.
216 This library is distributed in the hope that it will be useful,
217 but WITHOUT ANY WARRANTY; without even the implied warranty of
218 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
219 Lesser General Public License for more details.
221 You should have received a copy of the GNU Lesser General Public
222 License along with this library; if not, write to the Free Software
223 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA