Zipios++
deflateoutputstreambuf.cpp
Go to the documentation of this file.
1
2#include "zipios++/zipios-config.h"
3
4#include "zipios++/meta-iostreams.h"
5
6#include <zlib.h>
7
10
11#include "outputstringstream.h"
12
13namespace zipios {
14
15using std::cerr ;
16using std::endl ;
17
18DeflateOutputStreambuf::DeflateOutputStreambuf( streambuf *outbuf, bool user_init,
19 bool del_outbuf )
20 : FilterOutputStreambuf( outbuf, del_outbuf ),
21 _zs_initialized ( false ),
22 _invecsize ( 1000 ),
23 _invec ( _invecsize ),
24 _outvecsize ( 1000 ),
25 _outvec ( _outvecsize )
26{
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
31
32 // zlib init:
33 _zs.zalloc = Z_NULL ;
34 _zs.zfree = Z_NULL ;
35 _zs.opaque = Z_NULL ;
36
37 if ( user_init && ! init() )
38 cerr << "DeflateOutputStreambuf::reset() failed!\n" ; // FIXME: throw something
39
40}
41
42
46
47
48// This method is called in the constructor, so it must not write
49// anything to the output streambuf _outbuf (see notice in
50// constructor)
51bool DeflateOutputStreambuf::init( int comp_level ) {
52 static const int default_mem_level = 8 ;
53
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 ] ) ) ;
57 _zs.avail_in = 0 ;
58
59 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
60 _zs.avail_out = _outvecsize ;
61
62 int err ;
63 if( _zs_initialized ) { // just reset it
64 endDeflation() ;
65 err = deflateReset( &_zs ) ;
66 // FIXME: bug, for deflateReset we do not update the compression level
67 } else { // init it
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
71 written. */
72 _zs_initialized = true ;
73 }
74
75 // streambuf init:
76 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
77
78 _crc32 = crc32( 0, Z_NULL, 0 ) ;
79 _overflown_bytes = 0 ;
80
81 if ( err == Z_OK )
82 return true ;
83 else
84 return false ;
85}
86
87
88bool DeflateOutputStreambuf::closeStream() {
89 int err = Z_OK ;
90 if( _zs_initialized ) {
91 endDeflation() ;
92 err = deflateEnd( &_zs ) ;
93 _zs_initialized = false ;
94 }
95
96 if ( err == Z_OK )
97 return true ;
98 else {
99 cerr << "DeflateOutputStreambuf::closeStream(): deflateEnd failed" ;
100#ifdef HAVE_ZERROR
101 cerr << ": " << zError( err ) ;
102#endif
103 cerr << endl ;
104 return false ;
105 }
106}
107
108
109int DeflateOutputStreambuf::overflow( int c ) {
110 _zs.avail_in = pptr() - pbase() ;
111 _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
112
113 _crc32 = crc32( _crc32, _zs.next_in, _zs.avail_in ) ; // update crc32
114 _overflown_bytes += _zs.avail_in ;
115
116 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
117 _zs.avail_out = _outvecsize ;
118
119 // Deflate until _invec is empty.
120 int err = Z_OK ;
121 while ( ( _zs.avail_in > 0 || _zs.avail_out == 0 ) && err == Z_OK ) {
122 if ( _zs.avail_out == 0 )
123 flushOutvec() ;
124
125 err = deflate( &_zs, Z_NO_FLUSH ) ;
126 }
127
128 flushOutvec() ;
129
130 // Update 'put' pointers
131 setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
132
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" ;
138#ifdef HAVE_ZERROR
139 msgs << ": " << zError( err ) ;
140#endif
141 throw IOException( msgs.str() ) ;
142#endif
143 cerr << "Deflation failed\n" ;
144 return EOF ;
145 }
146
147 if ( c != EOF ) {
148 *pptr() = c ;
149 pbump( 1 ) ;
150 }
151
152 return 0 ;
153}
154
155int DeflateOutputStreambuf::sync() {
156 // FIXME: Do something
157// return overflow() ;
158 return 0 ;
159}
160
161
163 int deflated_bytes = _outvecsize - _zs.avail_out ;
164 int bc = _outbuf->sputn( &( _outvec[ 0 ] ), deflated_bytes ) ;
165
166 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
167 _zs.avail_out = _outvecsize ;
168
169 return deflated_bytes == bc ;
170}
171
172
174 overflow() ;
175
176 _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
177 _zs.avail_out = _outvecsize ;
178
179 // Deflate until _invec is empty.
180 int err = Z_OK ;
181
182 while ( err == Z_OK ) {
183 if ( _zs.avail_out == 0 )
184 flushOutvec() ;
185
186 err = deflate( &_zs, Z_FINISH ) ;
187 }
188
189 flushOutvec() ;
190
191 if ( err != Z_STREAM_END ) {
192 cerr << "DeflateOutputStreambuf::endDeflation(): deflation failed:\n" ;
193#ifdef HAVE_ZERROR
194 cerr << ": " << zError( err ) ;
195#endif
196 cerr << endl ;
197 }
198}
199
200
201} // namespace
202
207/*
208 Zipios++ - a small C++ library that provides easy access to .zip files.
209 Copyright (C) 2000 Thomas Søndergaard
210
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.
215
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.
220
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
224*/
void endDeflation()
Flushes the remaining data in the zlib buffers, after which the only possible operations are deflateE...
bool flushOutvec()
Flushes _outvec and updates _zs.next_out and _zs.avail_out.
DeflateOutputStreambuf(streambuf *outbuf, bool user_init=false, bool del_outbuf=false)
DeflateOutputStreambuf constructor.
A FilterOutputStreambuf is a streambuf that filters the data that is written to it before it passes i...
Header file that defines DeflateOutputStreambuf.
Header file that defines a number of exceptions used by FileCollection and its subclasses.
Header file that defines OutputStringStream.