~hikiko/nux/arb-srgba-shader

« back to all changes in this revision

Viewing changes to NuxCore/Zip/zipstream/zipstream.h

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 19:25:37 UTC
  • Revision ID: neil.patel@canonical.com-20100901192537-mfz7rm6q262pewg6
Import and build NuxCore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
zipstream Library License:
 
3
--------------------------
 
4
 
 
5
The zlib/libpng License Copyright (c) 2003 Jonathan de Halleux.
 
6
 
 
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.
 
8
 
 
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:
 
10
 
 
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.
 
12
 
 
13
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
 
14
 
 
15
3. This notice may not be removed or altered from any source distribution
 
16
 
 
17
Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003
 
18
*/
 
19
 
 
20
#ifndef ZIPSTREAM_HPP
 
21
#define ZIPSTREAM_HPP
 
22
 
 
23
#include <vector>
 
24
#include <iostream>
 
25
#include <algorithm>
 
26
#include <zlib/zlib.h>
 
27
#include <zlib/zutil.h>
 
28
 
 
29
namespace zlib_stream{
 
30
 
 
31
/// default gzip buffer size,
 
32
/// change this to suite your needs
 
33
const size_t default_buffer_size = 4096;
 
34
 
 
35
/// Compression strategy, see zlib doc.
 
36
enum EStrategy
 
37
{
 
38
        StrategyFiltered = 1,
 
39
        StrategyHuffmanOnly = 2,
 
40
        DefaultStrategy = 0
 
41
};
 
42
 
 
43
/** \brief A stream decorator that takes raw input and zips it to a ostream.
 
44
 
 
45
The class wraps up the inflate method of the zlib library 1.1.4 http://www.gzip.org/zlib/
 
46
*/
 
47
template<
 
48
        typename Elem, 
 
49
        typename Tr = std::char_traits<Elem>,
 
50
    typename ElemA = std::allocator<Elem>,
 
51
    typename ByteT = unsigned char,
 
52
    typename ByteAT = std::allocator<ByteT>
 
53
>       
 
54
class basic_zip_streambuf : public std::basic_streambuf<Elem, Tr> 
 
55
{
 
56
public:
 
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;
 
64
 
 
65
    /** Construct a zip stream
 
66
     * More info on the following parameters can be found in the zlib documentation.
 
67
     */
 
68
    basic_zip_streambuf(
 
69
                ostream_reference ostream_,
 
70
                size_t level_,
 
71
                EStrategy strategy_,
 
72
                size_t window_size_,
 
73
                size_t memory_level_,
 
74
                size_t buffer_size_
 
75
                );
 
76
        
 
77
        ~basic_zip_streambuf();
 
78
 
 
79
        int sync ();
 
80
    int_type overflow (int_type c);
 
81
 
 
82
        /** flushes the zip buffer and output buffer.
 
83
 
 
84
        This method should be called at the end of the compression. Calling flush multiple times, will lower the
 
85
        compression ratio.
 
86
        */
 
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;};
 
98
private:
 
99
        bool zip_to_stream( char_type*, std::streamsize);
 
100
        size_t fill_input_buffer();
 
101
 
 
102
        ostream_reference m_ostream;
 
103
        z_stream m_zip_stream;
 
104
    int m_err;
 
105
        byte_vector_type m_output_buffer;
 
106
        char_vector_type m_buffer; 
 
107
        long m_crc;
 
108
};
 
109
 
 
110
/** \brief A stream decorator that takes compressed input and unzips it to a istream.
 
111
 
 
112
The class wraps up the deflate method of the zlib library 1.1.4 http://www.gzip.org/zlib/
 
113
*/
 
114
template<
 
115
        typename Elem, 
 
116
        typename Tr = std::char_traits<Elem>,
 
117
    typename ElemA = std::allocator<Elem>,
 
118
    typename ByteT = unsigned char,
 
119
    typename ByteAT = std::allocator<ByteT>
 
120
>       
 
121
class basic_unzip_streambuf : 
 
122
        public std::basic_streambuf<Elem, Tr> 
 
123
{
 
124
public:
 
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;
 
132
 
 
133
     /** Construct a unzip stream
 
134
     * More info on the following parameters can be found in the zlib documentation.
 
135
     */
 
136
         basic_unzip_streambuf(
 
137
                istream_reference istream_,
 
138
                size_t window_size_,
 
139
                size_t read_buffer_size_,
 
140
                size_t input_buffer_size_
 
141
                );
 
142
        
 
143
        ~basic_unzip_streambuf();
 
144
 
 
145
    int_type underflow();
 
146
 
 
147
 
 
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;};
 
160
private:
 
161
        void put_back_from_zip_stream();
 
162
        std::streamsize unzip_from_stream( char_type*, std::streamsize);
 
163
 
 
164
        size_t fill_input_buffer();
 
165
 
 
166
        istream_reference m_istream;
 
167
        z_stream m_zip_stream;
 
168
    int m_err;
 
169
        byte_vector_type m_input_buffer;
 
170
        char_vector_type m_buffer; 
 
171
        long m_crc;
 
172
};
 
173
 
 
174
/*! \brief Base class for zip ostreams
 
175
 
 
176
Contains a basic_zip_streambuf.
 
177
*/
 
178
template<
 
179
        typename Elem, 
 
180
        typename Tr = std::char_traits<Elem>,
 
181
    typename ElemA = std::allocator<Elem>,
 
182
    typename ByteT = unsigned char,
 
183
    typename ByteAT = std::allocator<ByteT>
 
184
>       
 
185
class basic_zip_ostreambase : virtual public std::basic_ios<Elem,Tr>
 
186
{
 
187
public:
 
188
        typedef std::basic_ostream<Elem, Tr>& ostream_reference;
 
189
        typedef basic_zip_streambuf<
 
190
        Elem,
 
191
        Tr,
 
192
        ElemA,
 
193
        ByteT,
 
194
        ByteAT
 
195
        > zip_streambuf_type;
 
196
 
 
197
    /** Construct a zip stream
 
198
     * More info on the following parameters can be found in the zlib documentation.
 
199
     */
 
200
        basic_zip_ostreambase( 
 
201
                ostream_reference ostream_,
 
202
                size_t level_,
 
203
                EStrategy strategy_,
 
204
                size_t window_size_,
 
205
                size_t memory_level_,
 
206
                size_t buffer_size_
 
207
                )
 
208
                : m_buf(ostream_,level_,strategy_,window_size_,memory_level_,buffer_size_)
 
209
        {
 
210
                init(&m_buf );
 
211
        };
 
212
        
 
213
        /// returns the underlying zip ostream object
 
214
        zip_streambuf_type* rdbuf() { return &m_buf; };
 
215
 
 
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();};
 
224
private:
 
225
        zip_streambuf_type m_buf;
 
226
};
 
227
 
 
228
/*! \brief Base class for unzip istreams
 
229
 
 
230
Contains a basic_unzip_streambuf.
 
231
*/
 
232
template<
 
233
        typename Elem, 
 
234
        typename Tr = std::char_traits<Elem>,
 
235
    typename ElemA = std::allocator<Elem>,
 
236
    typename ByteT = unsigned char,
 
237
    typename ByteAT = std::allocator<ByteT>
 
238
>
 
239
class basic_zip_istreambase : virtual public std::basic_ios<Elem,Tr>
 
240
{
 
241
public:
 
242
        typedef std::basic_istream<Elem, Tr>& istream_reference;
 
243
        typedef basic_unzip_streambuf<
 
244
        Elem,
 
245
        Tr,
 
246
        ElemA,
 
247
        ByteT,
 
248
        ByteAT
 
249
        > unzip_streambuf_type;
 
250
 
 
251
        basic_zip_istreambase( 
 
252
                istream_reference ostream_,
 
253
                size_t window_size_,
 
254
                size_t read_buffer_size_,
 
255
                size_t input_buffer_size_
 
256
                )
 
257
                : m_buf(ostream_,window_size_, read_buffer_size_, input_buffer_size_)
 
258
        {
 
259
                init(&m_buf );
 
260
        };
 
261
        
 
262
        /// returns the underlying unzip istream object
 
263
        unzip_streambuf_type* rdbuf() { return &m_buf; };
 
264
 
 
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();};
 
273
private:
 
274
        unzip_streambuf_type m_buf;
 
275
};
 
276
 
 
277
/*! \brief A zipper ostream
 
278
 
 
279
This class is a ostream decorator that behaves 'almost' like any other ostream.
 
280
 
 
281
At construction, it takes any ostream that shall be used to output of the compressed data.
 
282
 
 
283
When finished, you need to call the special method zflush or call the destructor 
 
284
to flush all the intermidiate streams.
 
285
 
 
286
Example:
 
287
\code
 
288
// creating the target zip string, could be a fstream
 
289
ostringstream ostringstream_;
 
290
// creating the zip layer
 
291
zip_ostream zipper(ostringstream_);
 
292
 
 
293
        
 
294
// writing data 
 
295
zipper<<f<<" "<<d<<" "<<ui<<" "<<ul<<" "<<us<<" "<<c<<" "<<dum;
 
296
// zip ostream needs special flushing...
 
297
zipper.zflush();
 
298
\endcode
 
299
*/
 
300
template<
 
301
        typename Elem, 
 
302
        typename Tr = std::char_traits<Elem>,
 
303
    typename ElemA = std::allocator<Elem>,
 
304
    typename ByteT = unsigned char,
 
305
    typename ByteAT = std::allocator<ByteT>
 
306
>       
 
307
class basic_zip_ostream : 
 
308
        public basic_zip_ostreambase<Elem,Tr,ElemA,ByteT,ByteAT>, 
 
309
        public std::basic_ostream<Elem,Tr>
 
310
{
 
311
public:
 
312
        typedef basic_zip_ostreambase<
 
313
        Elem,Tr,ElemA,ByteT,ByteAT> zip_ostreambase_type;
 
314
        typedef std::basic_ostream<Elem,Tr> ostream_type;
 
315
 
 
316
        /** Constructs a zipper ostream decorator
 
317
         *
 
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
 
325
 
 
326
         When is_gzip_ is true, a gzip header and footer is automatically added.
 
327
         */
 
328
        basic_zip_ostream( 
 
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
 
337
                )
 
338
        : 
 
339
                zip_ostreambase_type(
 
340
            ostream_,
 
341
            level_,
 
342
            strategy_,
 
343
            window_size_,
 
344
            memory_level_,
 
345
            buffer_size_
 
346
            ), 
 
347
                m_is_gzip(is_gzip_),
 
348
                ostream_type(rdbuf())
 
349
        {
 
350
                if (m_is_gzip)
 
351
                        add_header();
 
352
        };
 
353
        ~basic_zip_ostream()
 
354
        {
 
355
                if (m_is_gzip)
 
356
                        add_footer();
 
357
        }
 
358
 
 
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()    
 
363
        {       
 
364
                flush(); rdbuf()->flush(); return *this; 
 
365
        };
 
366
 
 
367
private:
 
368
    static void put_long(ostream_reference out_, unsigned long x_);
 
369
 
 
370
        void add_header();
 
371
        void add_footer();
 
372
        bool m_is_gzip;
 
373
};
 
374
 
 
375
/*! \brief A zipper istream
 
376
 
 
377
This class is a istream decorator that behaves 'almost' like any other ostream.
 
378
 
 
379
At construction, it takes any istream that shall be used to input of the compressed data.
 
380
 
 
381
Simlpe example:
 
382
\code
 
383
// create a stream on zip string
 
384
istringstream istringstream_( ostringstream_.str());
 
385
// create unzipper istream
 
386
zip_istream unzipper( istringstream_);
 
387
 
 
388
// read and unzip
 
389
unzipper>>f_r>>d_r>>ui_r>>ul_r>>us_r>>c_r>>dum_r;
 
390
\endcode
 
391
*/
 
392
template<
 
393
        typename Elem, 
 
394
        typename Tr = std::char_traits<Elem>,
 
395
    typename ElemA = std::allocator<Elem>,
 
396
    typename ByteT = unsigned char,
 
397
    typename ByteAT = std::allocator<ByteT>
 
398
>
 
399
class basic_zip_istream : 
 
400
        public basic_zip_istreambase<Elem,Tr,ElemA,ByteT,ByteAT>, 
 
401
        public std::basic_istream<Elem,Tr>
 
402
{
 
403
public:
 
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;
 
408
 
 
409
        /** Construct a unzipper stream
 
410
         *
 
411
         * \param istream_ input buffer
 
412
         * \param window_size_ 
 
413
         * \param read_buffer_size_ 
 
414
         * \param input_buffer_size_ 
 
415
         */
 
416
        basic_zip_istream( 
 
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
 
421
                )
 
422
          : 
 
423
                zip_istreambase_type(istream_,window_size_, read_buffer_size_, input_buffer_size_), 
 
424
                istream_type(rdbuf()),
 
425
                m_is_gzip(false),
 
426
                m_gzip_crc(0),
 
427
                m_gzip_data_size(0)
 
428
        {
 
429
              if (rdbuf()->get_zerr()==Z_OK)
 
430
                          check_header();
 
431
        };
 
432
 
 
433
        /// returns true if it is a gzip file
 
434
        bool is_gzip() const                            {       return m_is_gzip;};
 
435
        /// reads the gzip header
 
436
        void read_footer();
 
437
        /** return crc check result
 
438
 
 
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.
 
441
 
 
442
        \return true if crc check is succesful 
 
443
        */
 
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;};
 
447
 
 
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;};
 
452
protected:
 
453
    static void read_long(istream_reference in_, unsigned long& x_);
 
454
 
 
455
        int check_header();
 
456
        bool m_is_gzip;
 
457
        unsigned long m_gzip_crc;
 
458
        unsigned long m_gzip_data_size;
 
459
};
 
460
 
 
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;
 
469
 
 
470
}; // zlib_sream
 
471
 
 
472
#include "zipstream.ipp"
 
473
 
 
474
#endif
 
475