2
zipstream Library License:
3
--------------------------
5
The zlib/libpng License Copyright (c) 2003 Jonathan de Halleux.
7
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
9
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
11
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
13
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15
3. This notice may not be removed or altered from any source distribution
17
Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003
26
#include <zlib/zlib.h>
27
#include <zlib/zutil.h>
29
namespace zlib_stream{
31
/// default gzip buffer size,
32
/// change this to suite your needs
33
const size_t default_buffer_size = 4096;
35
/// Compression strategy, see zlib doc.
39
StrategyHuffmanOnly = 2,
43
/** \brief A stream decorator that takes raw input and zips it to a ostream.
45
The class wraps up the inflate method of the zlib library 1.1.4 http://www.gzip.org/zlib/
49
typename Tr = std::char_traits<Elem>,
50
typename ElemA = std::allocator<Elem>,
51
typename ByteT = unsigned char,
52
typename ByteAT = std::allocator<ByteT>
54
class basic_zip_streambuf : public std::basic_streambuf<Elem, Tr>
57
typedef std::basic_ostream<Elem, Tr>& ostream_reference;
58
typedef ElemA char_allocator_type;
59
typedef ByteT byte_type;
60
typedef ByteAT byte_allocator_type;
61
typedef byte_type* byte_buffer_type;
62
typedef std::vector<byte_type, byte_allocator_type > byte_vector_type;
63
typedef std::vector<char_type, char_allocator_type > char_vector_type;
65
/** Construct a zip stream
66
* More info on the following parameters can be found in the zlib documentation.
69
ostream_reference ostream_,
77
~basic_zip_streambuf();
80
int_type overflow (int_type c);
82
/** flushes the zip buffer and output buffer.
84
This method should be called at the end of the compression. Calling flush multiple times, will lower the
87
std::streamsize flush();
88
/// returns a reference to the output stream
89
ostream_reference get_ostream() const { return m_ostream;};
90
/// returns the latest zlib error status
91
int get_zerr() const { return m_err;};
92
/// returns the crc of the input data compressed so far.
93
long get_crc() const { return m_crc;};
94
/// returns the size (bytes) of the input data compressed so far.
95
long get_in_size() const { return m_zip_stream.total_in;};
96
/// returns the size (bytes) of the compressed data so far.
97
long get_out_size() const { return m_zip_stream.total_out;};
99
bool zip_to_stream( char_type*, std::streamsize);
100
size_t fill_input_buffer();
102
ostream_reference m_ostream;
103
z_stream m_zip_stream;
105
byte_vector_type m_output_buffer;
106
char_vector_type m_buffer;
110
/** \brief A stream decorator that takes compressed input and unzips it to a istream.
112
The class wraps up the deflate method of the zlib library 1.1.4 http://www.gzip.org/zlib/
116
typename Tr = std::char_traits<Elem>,
117
typename ElemA = std::allocator<Elem>,
118
typename ByteT = unsigned char,
119
typename ByteAT = std::allocator<ByteT>
121
class basic_unzip_streambuf :
122
public std::basic_streambuf<Elem, Tr>
125
typedef std::basic_istream<Elem, Tr>& istream_reference;
126
typedef ElemA char_allocator_type;
127
typedef ByteT byte_type;
128
typedef ByteAT byte_allocator_type;
129
typedef byte_type* byte_buffer_type;
130
typedef std::vector<byte_type, byte_allocator_type > byte_vector_type;
131
typedef std::vector<char_type, char_allocator_type > char_vector_type;
133
/** Construct a unzip stream
134
* More info on the following parameters can be found in the zlib documentation.
136
basic_unzip_streambuf(
137
istream_reference istream_,
139
size_t read_buffer_size_,
140
size_t input_buffer_size_
143
~basic_unzip_streambuf();
145
int_type underflow();
148
/// returns the compressed input istream
149
istream_reference get_istream() { return m_istream;};
150
/// returns the zlib stream structure
151
z_stream& get_zip_stream() { return m_zip_stream;};
152
/// returns the latest zlib error state
153
int get_zerr() const { return m_err;};
154
/// returns the crc of the uncompressed data so far
155
long get_crc() const { return m_crc;};
156
/// returns the number of uncompressed bytes
157
long get_out_size() const { return m_zip_stream.total_out;};
158
/// returns the number of read compressed bytes
159
long get_in_size() const { return m_zip_stream.total_in;};
161
void put_back_from_zip_stream();
162
std::streamsize unzip_from_stream( char_type*, std::streamsize);
164
size_t fill_input_buffer();
166
istream_reference m_istream;
167
z_stream m_zip_stream;
169
byte_vector_type m_input_buffer;
170
char_vector_type m_buffer;
174
/*! \brief Base class for zip ostreams
176
Contains a basic_zip_streambuf.
180
typename Tr = std::char_traits<Elem>,
181
typename ElemA = std::allocator<Elem>,
182
typename ByteT = unsigned char,
183
typename ByteAT = std::allocator<ByteT>
185
class basic_zip_ostreambase : virtual public std::basic_ios<Elem,Tr>
188
typedef std::basic_ostream<Elem, Tr>& ostream_reference;
189
typedef basic_zip_streambuf<
195
> zip_streambuf_type;
197
/** Construct a zip stream
198
* More info on the following parameters can be found in the zlib documentation.
200
basic_zip_ostreambase(
201
ostream_reference ostream_,
205
size_t memory_level_,
208
: m_buf(ostream_,level_,strategy_,window_size_,memory_level_,buffer_size_)
213
/// returns the underlying zip ostream object
214
zip_streambuf_type* rdbuf() { return &m_buf; };
216
/// returns the zlib error state
217
int get_zerr() const { return m_buf.get_err();};
218
/// returns the uncompressed data crc
219
long get_crc() const { return m_buf.get_crc();};
220
/// returns the compressed data size
221
long get_out_size() const { return m_buf.get_out_size();};
222
/// returns the uncompressed data size
223
long get_in_size() const { return m_buf.get_in_size();};
225
zip_streambuf_type m_buf;
228
/*! \brief Base class for unzip istreams
230
Contains a basic_unzip_streambuf.
234
typename Tr = std::char_traits<Elem>,
235
typename ElemA = std::allocator<Elem>,
236
typename ByteT = unsigned char,
237
typename ByteAT = std::allocator<ByteT>
239
class basic_zip_istreambase : virtual public std::basic_ios<Elem,Tr>
242
typedef std::basic_istream<Elem, Tr>& istream_reference;
243
typedef basic_unzip_streambuf<
249
> unzip_streambuf_type;
251
basic_zip_istreambase(
252
istream_reference ostream_,
254
size_t read_buffer_size_,
255
size_t input_buffer_size_
257
: m_buf(ostream_,window_size_, read_buffer_size_, input_buffer_size_)
262
/// returns the underlying unzip istream object
263
unzip_streambuf_type* rdbuf() { return &m_buf; };
265
/// returns the zlib error state
266
int get_zerr() const { return m_buf.get_zerr();};
267
/// returns the uncompressed data crc
268
long get_crc() const { return m_buf.get_crc();};
269
/// returns the uncompressed data size
270
long get_out_size() const { return m_buf.get_out_size();};
271
/// returns the compressed data size
272
long get_in_size() const { return m_buf.get_in_size();};
274
unzip_streambuf_type m_buf;
277
/*! \brief A zipper ostream
279
This class is a ostream decorator that behaves 'almost' like any other ostream.
281
At construction, it takes any ostream that shall be used to output of the compressed data.
283
When finished, you need to call the special method zflush or call the destructor
284
to flush all the intermidiate streams.
288
// creating the target zip string, could be a fstream
289
ostringstream ostringstream_;
290
// creating the zip layer
291
zip_ostream zipper(ostringstream_);
295
zipper<<f<<" "<<d<<" "<<ui<<" "<<ul<<" "<<us<<" "<<c<<" "<<dum;
296
// zip ostream needs special flushing...
302
typename Tr = std::char_traits<Elem>,
303
typename ElemA = std::allocator<Elem>,
304
typename ByteT = unsigned char,
305
typename ByteAT = std::allocator<ByteT>
307
class basic_zip_ostream :
308
public basic_zip_ostreambase<Elem,Tr,ElemA,ByteT,ByteAT>,
309
public std::basic_ostream<Elem,Tr>
312
typedef basic_zip_ostreambase<
313
Elem,Tr,ElemA,ByteT,ByteAT> zip_ostreambase_type;
314
typedef std::basic_ostream<Elem,Tr> ostream_type;
316
/** Constructs a zipper ostream decorator
318
* \param ostream_ ostream where the compressed output is written
319
* \param is_gzip_ true if gzip header and footer have to be added
320
* \param level_ level of compression 0, bad and fast, 9, good and slower,
321
* \param strategy_ compression strategy
322
* \param window_size_ see zlib doc
323
* \param memory_level_ see zlib doc
324
* \param buffer_size_ the buffer size used to zip data
326
When is_gzip_ is true, a gzip header and footer is automatically added.
329
ostream_reference ostream_,
330
int open_mode = std::ios::out,
331
bool is_gzip_ = false,
332
size_t level_ = Z_DEFAULT_COMPRESSION,
333
EStrategy strategy_ = DefaultStrategy,
334
size_t window_size_ = 15,
335
size_t memory_level_ = 8,
336
size_t buffer_size_ = default_buffer_size
339
zip_ostreambase_type(
348
ostream_type(rdbuf())
359
/// returns true if it is a gzip
360
bool is_gzip() const { return m_is_gzip;};
361
/// flush inner buffer and zipper buffer
362
basic_zip_ostream<Elem,Tr>& zflush()
364
flush(); rdbuf()->flush(); return *this;
368
static void put_long(ostream_reference out_, unsigned long x_);
375
/*! \brief A zipper istream
377
This class is a istream decorator that behaves 'almost' like any other ostream.
379
At construction, it takes any istream that shall be used to input of the compressed data.
383
// create a stream on zip string
384
istringstream istringstream_( ostringstream_.str());
385
// create unzipper istream
386
zip_istream unzipper( istringstream_);
389
unzipper>>f_r>>d_r>>ui_r>>ul_r>>us_r>>c_r>>dum_r;
394
typename Tr = std::char_traits<Elem>,
395
typename ElemA = std::allocator<Elem>,
396
typename ByteT = unsigned char,
397
typename ByteAT = std::allocator<ByteT>
399
class basic_zip_istream :
400
public basic_zip_istreambase<Elem,Tr,ElemA,ByteT,ByteAT>,
401
public std::basic_istream<Elem,Tr>
404
typedef basic_zip_istreambase<
405
Elem,Tr,ElemA,ByteT,ByteAT> zip_istreambase_type;
406
typedef std::basic_istream<Elem,Tr> istream_type;
407
typedef unsigned char byte_type;
409
/** Construct a unzipper stream
411
* \param istream_ input buffer
412
* \param window_size_
413
* \param read_buffer_size_
414
* \param input_buffer_size_
417
istream_reference istream_,
418
size_t window_size_ = 15,
419
size_t read_buffer_size_ = default_buffer_size,
420
size_t input_buffer_size_ = default_buffer_size
423
zip_istreambase_type(istream_,window_size_, read_buffer_size_, input_buffer_size_),
424
istream_type(rdbuf()),
429
if (rdbuf()->get_zerr()==Z_OK)
433
/// returns true if it is a gzip file
434
bool is_gzip() const { return m_is_gzip;};
435
/// reads the gzip header
437
/** return crc check result
439
When you have finished reading the compressed data, call read_footer to read the uncompressed data crc.
440
This method compares it to the crc of the uncompressed data.
442
\return true if crc check is succesful
444
bool check_crc() const { return get_crc() == m_gzip_crc;};
445
/// return data size check
446
bool check_data_size() const { return get_out_size() == m_gzip_data_size;};
448
/// return the crc value in the file
449
long get_gzip_crc() const { return m_gzip_crc;};
450
/// return the data size in the file
451
long get_gzip_data_size() const { return m_gzip_data_size;};
453
static void read_long(istream_reference in_, unsigned long& x_);
457
unsigned long m_gzip_crc;
458
unsigned long m_gzip_data_size;
461
/// A typedef for basic_zip_ostream<char>
462
typedef basic_zip_ostream<char> zip_ostream;
463
/// A typedef for basic_zip_ostream<wchar_t>
464
typedef basic_zip_ostream<wchar_t> zip_wostream;
465
/// A typedef for basic_zip_istream<char>
466
typedef basic_zip_istream<char> zip_istream;
467
/// A typedef for basic_zip_istream<wchart>
468
typedef basic_zip_istream<wchar_t> zip_wistream;
472
#include "zipstream.ipp"